library(plotly)
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio

Attaching package: ‘plotly’

The following object is masked from ‘package:ggplot2’:

    last_plot

The following object is masked from ‘package:stats’:

    filter

The following object is masked from ‘package:graphics’:

    layout

0.1 Load all of the throw data

# Note: this notebook right now REQUIRES that the analysis notebook be run to
# make the fits, or that the data folder contains the fits

# load omnibus dataframe
omnibus_df <- read_delim("../data/processed/omnibus/omnibus_raw.csv",
  delim = ",",
  col_types = cols(
    .default = col_double(),
    type = col_factor(),
    ppid = col_factor(),
    exp_label = col_factor(),
    experiment = col_factor(),
    hand = col_factor(),
    camera_tilt = col_factor(),
    surface_tilt = col_factor(),
    target = col_factor(),
    test_type = col_factor(),
    phase = col_factor(),
    learning_and_decay_curves = col_factor(),
    prior_anim = col_factor(),
    baseline_block = col_logical(),
    alt_washout_block = col_logical(),
    alt_all_washout_block = col_logical(),
    task_type = col_factor(),
    surface = col_factor(),
    anim_type = col_factor()
  )
) %>% # filter out practice blocks
  filter(
    block_num > 4,
    !(ppid %in% c(2, 81, 82, 83))
  )

# load exponential decay fits
init_learning_rates <- read_csv(
  "../data/processed/learning_rate_df.csv",
  col_types = cols(
    .default = col_double(),
    experiment = col_factor(),
    phase = col_factor()
  )
) %>%
  mutate(experiment = factor(
    experiment,
    levels = c(
      "accel_cued_tilt", "accel_uncued",
      "curved_cued_tilt", "curved_uncued",
      "rot30_cued_tilt", "rot30_uncued",
      "rot15_cued_tilt", "rot15_uncued",
      "a_ball_roll_animate_surface"
    )
  ))

init_learning_rates_3par <- read_csv(
  "../data/processed/learning_rate_df_3par.csv",
  col_types = cols(
    .default = col_double(),
    experiment = col_factor(),
    phase = col_factor()
  )
) %>%
  mutate(experiment = factor(
    experiment,
    levels = c(
      "accel_cued_tilt", "accel_uncued",
      "curved_cued_tilt", "curved_uncued",
      "rot30_cued_tilt", "rot30_uncued",
      "rot15_cued_tilt", "rot15_uncued",
      "a_ball_roll_animate_surface"
    )
  ))

anim_learning_rates <- read_csv(
  "../data/processed/learning_rate_df_anim.csv",
  col_types = cols(
    .default = col_double(),
    ppid = col_factor(),
    experiment = col_factor(),
    phase = col_factor()
  )
) %>%
  mutate(experiment = factor(
    experiment,
    levels = c(
      "rot30_cued_tilt", "rot30_uncued",
      "half_anim", "full_anim"
    )
  ))

alt_washout_rates <- read_csv(
  "../data/processed/exp_fits_alt_washout_curves.csv",
  col_types = cols(
    .default = col_double(),
    experiment = col_factor(),
    phase = col_factor()
    )
  ) %>%
  mutate(experiment = factor(
    experiment, 
    levels = c(
      "accel_cued_tilt", "accel_uncued",
      "curved_cued_tilt", "curved_uncued",
      "rot30_cued_tilt", "rot30_uncued",
      "rot15_cued_tilt", "rot15_uncued",
      "a_ball_roll_animate_surface"
      )
    )
  )

fitted_learning_rate_df <- read_csv(
  "../data/processed/fit_curves/fitted_learning_rate_df.csv",
  col_types = cols(
    .default = col_double(),
    experiment = col_factor(),
    phase = col_factor()
  )
) %>%
  mutate(experiment = factor(
    experiment,
    levels = c(
      "accel_cued_tilt", "accel_uncued",
      "curved_cued_tilt", "curved_uncued",
      "rot30_cued_tilt", "rot30_uncued",
      "rot15_cued_tilt", "rot15_uncued",
      "a_ball_roll_animate_surface"
    )
  ))

fitted_alt_washout_df <- read_csv(
  "../data/processed/fit_curves/fitted_exp_fits_alt_washout_curves.csv",
  col_types = cols(
    .default = col_double(),
    experiment = col_factor(),
    phase = col_factor()
  )
) %>%
  mutate(experiment = factor(
    experiment,
    levels = c(
      "accel_cued_tilt", "accel_uncued",
      "curved_cued_tilt", "curved_uncued",
      "rot30_cued_tilt", "rot30_uncued",
      "rot15_cued_tilt", "rot15_uncued",
      "a_ball_roll_animate_surface"
    )
  ))
# use flick_direction_x, y, and z to get magnitude of flick direction
omnibus_df$magnitude <- sqrt(omnibus_df$flick_direction_x^2 + omnibus_df$flick_direction_y^2 + omnibus_df$flick_direction_z^2)

1 Success Manifolds - Accelerated Groups

For these plots, we will use data only from the training phase (transfer too?). Baseline phases and washout phases are the same for all groups.

data_per_trial <- omnibus_df %>%
  filter(
    phase == "training",
    experiment %in% c("accel_uncued", "accel_cued_tilt")
  )

# Note for figure: facet by target

# set up the plot
p <- data_per_trial %>%
  ggplot(aes(
    x = raw_throw_deviation,
    y = magnitude,
    color = raw_error_size
  )) +
  # vertical line at 0
  # geom_vline(xintercept = 0, linetype = "dashed", color = "#CCCCCC") +
  # colour palette
  scale_colour_gradient(
    low = "#7eaee2", high = "#001a35",
    limits = c(.05, .70), na.value = "white" # Note: max error value is ~68, target radius is 5
  ) +
  # add data points
  geom_point(size = 1.3, alpha = 0.7, stroke = 0) +
  # facet
  facet_wrap(~ fct_relevel(target, "96", "92", "88", "84"), nrow = 1) +
  # theme
  theme_classic() +
  labs(
    x = NULL,
    y = "Throw Speed (m/s)"
  ) +
  theme(
    panel.background = element_rect(
      fill = "#000000",
      colour = "#000000"
    ),
    legend.position = "none",
    text = element_text(size = text_size),
    strip.background = element_blank(), # facet labels
    strip.text.x = element_blank()
  ) +
  scale_y_continuous(limits = c(1.7, 2.2)) +
  scale_x_continuous(limits = c(-60, 10))

# save
if (save_plots) {
  ggsave(
    p,
    filename = "../data/figs/paper_figs/fig3_manifolds_accel.pdf", device = "pdf",
    height = 1.7, width = 7.2
  )
}

ggplotly(p)

# p
data_per_trial <- omnibus_df %>%
  filter(
    phase == "training",
    experiment %in% c("rot30_uncued", "rot30_cued_tilt")
  )

# Note for figure: facet by target

# set up the plot
p <- data_per_trial %>%
  ggplot(aes(
    x = raw_throw_deviation,
    y = magnitude,
    color = raw_error_size
    # shape = ppid
  )) +
  # vertical line at 0
  geom_vline(xintercept = -30, linetype = "dashed", color = "#CCCCCC") +
  # colour palette
  scale_colour_gradient(
    low = "#7eaee2", high = "#001a35",
    limits = c(.05, .70), na.value = "white" # Note: max error value is ~68, target radius is 5
  ) +
  # add data points
  geom_point(size = 1.3, alpha = 0.7, stroke = 0) +
  # facet
  facet_wrap(~ fct_relevel(target, "96", "92", "88", "84"), nrow = 1) +
  # theme
  theme_classic() +
  labs(
    x = NULL,
    y = "Throw Speed (m/s)"
  ) +
  theme(
    panel.background = element_rect(
      fill = "#000000",
      colour = "#000000"
    ),
    legend.position = "none",
    text = element_text(size = text_size),
    strip.background = element_blank(), # facet labels
    strip.text.x = element_blank()
  ) +
  scale_y_continuous(limits = c(1.7, 2.2)) +
  scale_x_continuous(limits = c(-60, 10))

# save
if (save_plots) {
  ggsave(
    p,
    filename = "../data/figs/paper_figs/fig3_manifolds_rotated.pdf", device = "pdf",
    height = 1.7, width = 7.2
  )
}

# ggplotly(p)
p

data_per_trial <- omnibus_df %>%
  filter(
    phase == "training",
    experiment %in% c("curved_cued_tilt", "curved_uncued")
  )

# Note for figure: facet by target

# set up the plot
p <- data_per_trial %>%
  ggplot(aes(
    x = raw_throw_deviation,
    y = magnitude,
    color = raw_error_size
    # shape = ppid
  )) +
  # vertical line at 30
  geom_vline(xintercept = -30, linetype = "dashed", color = "#CCCCCC") +
  # colour palette
  scale_colour_gradient(
    low = "#7eaee2", high = "#001a35",
    limits = c(.05, .70), na.value = "white" # Note: max error value is ~68, target radius is 5
  ) +
  # add data points
  geom_point(size = 1.3, alpha = 0.7, stroke = 0) +
  # facet
  facet_wrap(~ fct_relevel(target, "96", "92", "88", "84"), nrow = 1) +
  # theme
  theme_classic() +
  labs(
    x = NULL,
    y = "Throw Speed (m/s)"
  ) +
  theme(
    panel.background = element_rect(
      fill = "#000000",
      colour = "#000000"
    ),
    legend.position = "none",
    text = element_text(size = text_size),
    strip.background = element_blank(), # facet labels
    strip.text.x = element_blank()
  ) +
  scale_y_continuous(limits = c(1.7, 2.2)) +
  scale_x_continuous(limits = c(-60, 10))

# save
if (save_plots) {
  ggsave(
    p,
    filename = "../data/figs/paper_figs/fig3_manifolds_curved.pdf", device = "pdf",
    height = 1.7, width = 7.2
  )
}

# ggplotly(p)
p

num_exps <- 4

1.1 Normalized Training Phases

# rest of the exps
data_per_group <- omnibus_df %>%
  filter(
    experiment %in% c(
      "rot30_cued_tilt", "rot30_uncued",
      "curved_cued_tilt", "curved_uncued"
    ),
    trial_num >= 214,
    phase == "training",
    learning_and_decay_curves == 1
  ) %>%
  group_by(experiment, phase, test_type, trial_num) %>%
  summarise(
    mean_deviation = mean(norm_throw_deviation),
    ci_deviation = vector_confint(norm_throw_deviation),
    .groups = "drop"
  ) %>%
  arrange(experiment, trial_num)

# add a dummy column with repeating sequence
# NOTE: this can't be combined with above since we are using nrow
data_per_group <- data_per_group %>%
  mutate(dummy_x = rep(1:(nrow(data_per_group) / num_exps),
    length.out = nrow(data_per_group)
  ))

# set up plot
p <- data_per_group %>%
  ggplot(
    aes(
      x = dummy_x, y = mean_deviation, colour = experiment
    )
  ) +
  theme_classic() +
  theme(
    legend.position = "none",
    text = element_text(size = text_size)
  ) +
  labs(
    x = "Trial",
    y = "Normalized Throw Angle"
  ) +
  # add horizontal lines
  geom_hline(
    yintercept = c(0, 1), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "solid"
  ) +
  geom_hline(
    yintercept = c(0.5, 1.5), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "dashed"
  ) +
  # set colour palette
  scale_colour_manual(values = pallete_list) +
  scale_fill_manual(values = pallete_list) + # scale axes
  scale_y_continuous(
    breaks = c(0, 0.5, 1, 1.5),
    labels = c(0, 0.5, 1, 1.5),
    limits = c(-0.2, 1.5)
  ) +
  scale_x_continuous(
    breaks = curve_x_breaks,
    labels = curve_x_breaks
  )

# add confidence intervals and data points
for (uniq_phase in unique(data_per_group$phase)) {
  # get the data for this block
  to_plot_data <- filter(data_per_group, phase == uniq_phase)

  p <- p + geom_ribbon(
    data = to_plot_data,
    aes(
      ymin = mean_deviation - ci_deviation,
      ymax = mean_deviation + ci_deviation,
      fill = experiment
    ), colour = NA, alpha = 0.3
  ) + geom_line(
    data = to_plot_data
  )
}

# save
if (save_plots) {
  ggsave(
    p,
    filename = "../data/figs/paper_figs/fig3_exps_normalized_training.pdf", device = "pdf",
    height = 2, width = curve_fig_width
  )
}

p

fitted_data <- fitted_learning_rate_df %>%
  filter(
    experiment %in% c(
      "rot30_cued_tilt", "rot30_uncued",
      "curved_cued_tilt", "curved_uncued"
    ),
    phase == "training"
  ) %>%
  mutate(
    pert = factor(str_split_fixed(experiment, "_", 2)[, 1]),
    cue = factor(str_split_fixed(experiment, "_", 2)[, 2])
  )

p <- fitted_data %>%
  ggplot(
    aes(x = x + 1, y = y, colour = experiment)
  ) +
  theme_classic() +
  theme(
    legend.position = "none",
    text = element_text(size = text_size)
  ) +
  labs(
    x = "Trial",
    y = "Normalized Throw Angle"
  ) +
  # add horizontal lines
  geom_hline(
    yintercept = c(0, 1), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "solid"
  ) +
  geom_hline(
    yintercept = c(0.5, 1.5), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "dashed"
  ) +
  # set colour palette
  scale_colour_manual(values = pallete_list) +
  scale_fill_manual(values = pallete_list) + # scale axes
  scale_y_continuous(
    breaks = c(0, 0.5, 1, 1.5),
    labels = c(0, 0.5, 1, 1.5),
    limits = c(-0.2, 1.5)
  ) +
  scale_x_continuous(
    breaks = curve_x_breaks,
    labels = curve_x_breaks
  ) +
  geom_line()

# save
if (save_plots) {
  ggsave(
    p,
    filename = "../data/figs/paper_figs/fig3_curved_training_fitted_only.pdf", device = "pdf",
    height = 2, width = curve_fig_width
  )
}

p

1.2 Training - Fit Learning Rates

data_per_ppt <- init_learning_rates %>%
  filter(
    experiment %in% c(
      "rot30_cued_tilt", "rot30_uncued",
      "curved_cued_tilt", "curved_uncued"
    ),
    phase == "training"
  ) %>%
  mutate(
    pert = factor(str_split_fixed(experiment, "_", 2)[, 1]),
    cue = factor(str_split_fixed(experiment, "_", 2)[, 2]),
    ppid = factor(ppid)
  )

data_per_group <- data_per_ppt %>%
  group_by(experiment, phase) %>%
  summarise(
    mean_learning_rate = mean(exp_fit_lambda),
    ci_learning_rate = vector_confint(exp_fit_lambda),
    mean_high = mean(exp_fit_N0),
    ci_high = vector_confint(exp_fit_N0),
    n = n(),
    .groups = "drop"
  )

p <- data_per_group %>%
  ggplot(
    aes(x = experiment, y = mean_learning_rate, colour = experiment)
  ) +
  theme_classic() +
  labs(
    x = per_group_x_labs,
    y = "Learning Rate"
  ) +
  # remove all x axis labels
  theme(
    legend.position = "none",
    text = element_text(size = text_size)
  ) +
  # colour legend settings
  guides(
    colour = guide_legend(override.aes = list(alpha = 1))
  ) +
  # set colour palette
  scale_colour_manual(values = pallete_list) +
  scale_fill_manual(
    values = pallete_list
  ) +
  # add horizontal lines
  geom_hline(
    yintercept = c(0, 1), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "solid"
  ) +
  geom_hline(
    yintercept = c(0.25, 0.5, 0.75), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "dashed"
  ) +
  # y-axis scale
  scale_y_continuous(
    # limits = c(-35, 5),
    breaks = c(0, 0.25, 0.5, 0.75, 1),
    labels = c(0, 0.25, 0.5, 0.75, 1)
  ) +
  scale_x_discrete(
    labels = c(0, 0, 0, 0)
  ) +
  # add data points
  geom_beeswarm(
    data = data_per_ppt,
    aes(
      y = exp_fit_lambda
    ),
    alpha = 0.1,
    size = 1
  ) +
  geom_linerange(aes(
    ymin = mean_learning_rate - ci_learning_rate,
    ymax = mean_learning_rate + ci_learning_rate
  ), alpha = 0.5, lwd = 2) +
  geom_point()

# save
if (save_plots) {
  ggsave(
    p,
    filename = "../data/figs/paper_figs/fig3_training_learning_rates.pdf", device = "pdf",
    height = 2, width = per_group_fig_width
  )
}

p

1.2.1 ANOVA - 3 levels

(temp_ANOVA <- aov_car(
  exp_fit_lambda ~ pert * cue + Error(ppid),
  data_per_ppt,
  include_aov = TRUE
))
Contrasts set to contr.sum for the following variables: pert, cue
Anova Table (Type 3 tests)

Response: exp_fit_lambda
    Effect    df  MSE         F  ges p.value
1     pert 1, 77 0.06 12.88 *** .143   <.001
2      cue 1, 77 0.06   7.60 ** .090    .007
3 pert:cue 1, 77 0.06    3.11 + .039    .082
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘+’ 0.1 ‘ ’ 1
print("Bayes anovas and bayes factors:")
[1] "Bayes anovas and bayes factors:"
print("")
[1] ""
bf <- anovaBF(exp_fit_lambda ~ pert * cue, data = data.frame(data_per_ppt), progress = FALSE)
print(bf)
Bayes factor analysis
--------------
[1] pert                  : 33.67806 ±0%
[2] cue                   : 4.088725 ±0.01%
[3] pert + cue            : 190.7611 ±0.64%
[4] pert + cue + pert:cue : 201.0003 ±0.86%

Against denominator:
  Intercept only 
---
Bayes factor type: BFlinearModel, JZS
print(bayesfactor_inclusion(bf))
Inclusion Bayes Factors (Model Averaged)

         P(prior) P(posterior) Inclusion BF
pert         0.60         0.99        55.74
cue          0.60         0.92         7.61
cue:pert     0.20         0.47         3.50

* Compared among: all models
*    Priors odds: uniform-equal
# Note: default multiplicity correction for pairs summary is Tukey HSD
print("----------------------------- EMMs -----------------------------")
[1] "----------------------------- EMMs -----------------------------"
emms_obj <- emmeans(temp_ANOVA, "pert")
NOTE: Results may be misleading due to involvement in interactions
print(pwpm(emms_obj, diffs = FALSE))
        curved   rot30
curved [0.527]  0.0006
rot30          [0.329]

Row and column labels: pert
Upper triangle: P values 
Diagonal: [Estimates] (emmean) 
print("----------------------------- EMMs -----------------------------")
[1] "----------------------------- EMMs -----------------------------"
emms_obj <- emmeans(temp_ANOVA, "cue")
NOTE: Results may be misleading due to involvement in interactions
print(pwpm(emms_obj, diffs = FALSE))
          cued_tilt  uncued
cued_tilt   [0.504]  0.0073
uncued              [0.352]

Row and column labels: cue
Upper triangle: P values 
Diagonal: [Estimates] (emmean) 
# Effect size is Cohen's D
eff_size(emms_obj, edf = temp_ANOVA$anova_table$`den Df`[1], sigma = sigma(temp_ANOVA$lm))
 contrast           effect.size    SE df lower.CL upper.CL
 cued_tilt - uncued       0.613 0.228 77    0.159     1.07

Results are averaged over the levels of: pert 
sigma used for effect sizes: 0.2484 
Confidence level used: 0.95 
print("----------------------------- Full Tukey HSD -----------------------------")
[1] "----------------------------- Full Tukey HSD -----------------------------"
print(TukeyHSD(temp_ANOVA$aov))
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = tmp_formula, data = dat.ret, contrasts = contrasts)

$pert
                   diff        lwr         upr     p adj
rot30-curved -0.2012278 -0.3111615 -0.09129398 0.0004837

$cue
                      diff        lwr         upr     p adj
uncued-cued_tilt -0.153335 -0.2632687 -0.04340118 0.0068789

$`pert:cue`
                                        diff        lwr         upr     p adj
rot30:cued_tilt-curved:cued_tilt -0.10082813 -0.3071210  0.10546473 0.5761442
curved:uncued-curved:cued_tilt   -0.05482835 -0.2611212  0.15146451 0.8975670
rot30:uncued-curved:cued_tilt    -0.35036936 -0.5541916 -0.14654716 0.0001305
curved:uncued-rot30:cued_tilt     0.04599978 -0.1602931  0.25229263 0.9361528
rot30:uncued-rot30:cued_tilt     -0.24954123 -0.4533634 -0.04571903 0.0100884
rot30:uncued-curved:uncued       -0.29554100 -0.4993632 -0.09171880 0.0015670
print(eff_size(emmeans(temp_ANOVA$aov, c("pert", "cue")),
  edf = temp_ANOVA$anova_table$`den Df`[1],
  sigma = sigma(temp_ANOVA$lm)
))
 contrast                           effect.size    SE df lower.CL upper.CL
 curved cued_tilt - rot30 cued_tilt       0.406 0.318 77   -0.227    1.039
 curved cued_tilt - curved uncued         0.221 0.317 77   -0.410    0.851
 curved cued_tilt - rot30 uncued          1.410 0.332 77    0.748    2.072
 rot30 cued_tilt - curved uncued         -0.185 0.317 77   -0.816    0.445
 rot30 cued_tilt - rot30 uncued           1.005 0.323 77    0.362    1.647
 curved uncued - rot30 uncued             1.190 0.327 77    0.539    1.840

sigma used for effect sizes: 0.2484 
Confidence level used: 0.95 

1.3 Training - Fit High Points (Asymptotes)

p <- data_per_group %>%
  ggplot(
    aes(x = experiment, y = mean_high, colour = experiment)
  ) +
  theme_classic() +
  labs(
    x = per_group_x_labs,
    y = "Asymptote of Adaptation"
  ) +
  # for the colour legend, only show the first 7
  # Note this doesn't work for the plotly plot
  guides(
    colour = guide_legend(override.aes = list(alpha = 1))
  ) +
  # set colour palette
  scale_colour_manual(values = pallete_list) +
  scale_fill_manual(values = pallete_list) +
  # add horizontal lines
  geom_hline(
    yintercept = c(1), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "solid"
  ) +
  geom_hline(
    yintercept = c(0.5, 1.5), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "dashed"
  ) +
  # y-axis scale
  scale_y_continuous(
    limits = c(0.5, 1.75),
    breaks = c(0.5, 0.75, 1, 1.25, 1.5),
    labels = c(0.5, 0.75, 1, 1.25, 1.5)
  ) +
  scale_x_discrete(
    labels = c(0, 0, 0, 0)
  ) +
  # remove all x axis labels
  theme(
    legend.position = "none",
    text = element_text(size = text_size)
  ) +
  # add data points
  geom_beeswarm(
    data = data_per_ppt,
    aes(
      y = exp_fit_N0
    ),
    alpha = 0.1,
    size = 1
  ) +
  geom_linerange(aes(
    ymin = mean_high - ci_high,
    ymax = mean_high + ci_high
  ), alpha = 0.5, lwd = 2) +
  geom_point()

# save
if (save_plots) {
  ggsave(
    p,
    filename = "../data/figs/paper_figs/fig3_training_asymptotes.pdf", device = "pdf",
    height = 2, width = per_group_fig_width
  )
}

p

1.3.1 ANOVA - 3 levels

(temp_ANOVA <- aov_car(
  exp_fit_N0 ~ pert * cue + Error(ppid),
  data_per_ppt,
  include_aov = TRUE
))
Contrasts set to contr.sum for the following variables: pert, cue
Anova Table (Type 3 tests)

Response: exp_fit_N0
    Effect    df  MSE    F  ges p.value
1     pert 1, 77 0.02 1.57 .020    .214
2      cue 1, 77 0.02 0.25 .003    .621
3 pert:cue 1, 77 0.02 0.31 .004    .582
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘+’ 0.1 ‘ ’ 1
print("Bayes anovas and bayes factors:")
[1] "Bayes anovas and bayes factors:"
print("")
[1] ""
bf <- anovaBF(exp_fit_N0 ~ pert * cue, data = data.frame(data_per_ppt), progress = FALSE)
print(bf)
Bayes factor analysis
--------------
[1] pert                  : 0.4618912  ±0.01%
[2] cue                   : 0.2583483  ±0.02%
[3] pert + cue            : 0.1183708  ±0.99%
[4] pert + cue + pert:cue : 0.04131614 ±1.34%

Against denominator:
  Intercept only 
---
Bayes factor type: BFlinearModel, JZS
print(bayesfactor_inclusion(bf))
Inclusion Bayes Factors (Model Averaged)

         P(prior) P(posterior) Inclusion BF
pert         0.60         0.33        0.329
cue          0.60         0.22        0.191
cue:pert     0.20         0.02        0.090

* Compared among: all models
*    Priors odds: uniform-equal
# Note: default multiplicity correction for pairs summary is Tukey HSD
print("----------------------------- EMMs -----------------------------")
[1] "----------------------------- EMMs -----------------------------"
emms_obj <- emmeans(temp_ANOVA, "pert")
NOTE: Results may be misleading due to involvement in interactions
print(pwpm(emms_obj, diffs = FALSE))
       curved  rot30
curved [1.08] 0.2142
rot30         [1.03]

Row and column labels: pert
Upper triangle: P values 
Diagonal: [Estimates] (emmean) 
# Effect size is Cohen's D
eff_size(emms_obj, edf = temp_ANOVA$anova_table$`den Df`[1], sigma = sigma(temp_ANOVA$lm))
 contrast       effect.size    SE df lower.CL upper.CL
 curved - rot30       0.278 0.223 77   -0.166    0.723

Results are averaged over the levels of: cue 
sigma used for effect sizes: 0.1479 
Confidence level used: 0.95 
print("----------------------------- Full Tukey HSD -----------------------------")
[1] "----------------------------- Full Tukey HSD -----------------------------"
print(TukeyHSD(temp_ANOVA$aov))
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = tmp_formula, data = dat.ret, contrasts = contrasts)

$pert
                    diff        lwr        upr     p adj
rot30-curved -0.04113983 -0.1065787 0.02429902 0.2144126

$cue
                        diff         lwr        upr     p adj
uncued-cued_tilt -0.01610158 -0.08154043 0.04933727 0.6255562

$`pert:cue`
                                         diff         lwr        upr     p adj
rot30:cued_tilt-curved:cued_tilt -0.059316474 -0.18211375 0.06348080 0.5856122
curved:uncued-curved:cued_tilt   -0.034477005 -0.15727428 0.08832027 0.8817483
rot30:uncued-curved:cued_tilt    -0.057484866 -0.17881146 0.06384173 0.6009106
curved:uncued-rot30:cued_tilt     0.024839469 -0.09795781 0.14763675 0.9512295
rot30:uncued-rot30:cued_tilt      0.001831608 -0.11949499 0.12315821 0.9999774
rot30:uncued-curved:uncued       -0.023007861 -0.14433446 0.09831874 0.9592907
print(eff_size(emmeans(temp_ANOVA$aov, c("pert", "cue")),
  edf = temp_ANOVA$anova_table$`den Df`[1],
  sigma = sigma(temp_ANOVA$lm)
))
 contrast                           effect.size    SE df lower.CL upper.CL
 curved cued_tilt - rot30 cued_tilt      0.4011 0.318 77   -0.232    1.034
 curved cued_tilt - curved uncued        0.2332 0.317 77   -0.398    0.864
 curved cued_tilt - rot30 uncued         0.3887 0.314 77   -0.237    1.014
 rot30 cued_tilt - curved uncued        -0.1680 0.317 77   -0.798    0.462
 rot30 cued_tilt - rot30 uncued         -0.0124 0.312 77   -0.635    0.610
 curved uncued - rot30 uncued            0.1556 0.313 77   -0.467    0.778

sigma used for effect sizes: 0.1479 
Confidence level used: 0.95 

1.4 Normalized Washout Phases

# rest of the exps
data_per_group <- omnibus_df %>%
  filter(
    experiment %in% c(
      "rot30_cued_tilt", "rot30_uncued",
      "curved_cued_tilt", "curved_uncued"
    ),
    trial_num >= 214,
    phase == "washout",
    learning_and_decay_curves == 1
  ) %>%
  group_by(experiment, phase, trial_num) %>%
  summarise(
    mean_deviation = mean(norm_throw_deviation),
    ci_deviation = vector_confint(norm_throw_deviation),
    .groups = "drop"
  ) %>%
  arrange(experiment, trial_num)

# add a dummy column with repeating sequence
# NOTE: this can't be combined with above since we are using nrow
data_per_group <- data_per_group %>%
  mutate(dummy_x = rep(1:(nrow(data_per_group) / num_exps),
    length.out = nrow(data_per_group)
  ))

# set up plot
p <- data_per_group %>%
  ggplot(
    aes(
      x = dummy_x, y = mean_deviation, colour = experiment
    )
  ) +
  theme_classic() +
  theme(
    legend.position = "none",
    text = element_text(size = text_size)
  ) +
  labs(
    x = "Trial",
    y = "Normalized Throw Angle"
  ) +
  # add horizontal lines
  geom_hline(
    yintercept = c(0, 1), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "solid"
  ) +
  geom_hline(
    yintercept = c(0.5, 1.5), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "dashed"
  ) +
  # set colour palette
  scale_colour_manual(values = pallete_list) +
  scale_fill_manual(values = pallete_list) + # scale axes
  scale_y_continuous(
    breaks = c(0, 0.5, 1, 1.5),
    labels = c(0, 0.5, 1, 1.5)
  ) +
  scale_x_continuous(
    breaks = curve_x_breaks,
    labels = curve_x_breaks
  )

# add confidence intervals and data points
for (uniq_phase in unique(data_per_group$phase)) {
  # get the data for this block
  to_plot_data <- filter(data_per_group, phase == uniq_phase)

  p <- p + geom_ribbon(
    data = to_plot_data,
    aes(
      ymin = mean_deviation - ci_deviation,
      ymax = mean_deviation + ci_deviation,
      fill = experiment
    ), colour = NA, alpha = 0.3
  ) + geom_line(
    data = to_plot_data
  )
}

# save
if (save_plots) {
  ggsave(
    p,
    filename = "../data/figs/paper_figs/fig3_normalized_washout.pdf", device = "pdf",
    height = 2, width = 2.5
  )
}

p

1.5 Washout - Fit Learning Rates

data_per_ppt <- init_learning_rates %>%
  filter(
    experiment %in% c(
      "rot30_cued_tilt", "rot30_uncued",
      "curved_cued_tilt", "curved_uncued"
    ),
    phase == "washout"
  ) %>%
  mutate(
    pert = factor(str_split_fixed(experiment, "_", 2)[, 1]),
    cue = factor(str_split_fixed(experiment, "_", 2)[, 2]),
    ppid = factor(ppid)
  )

data_per_group <- data_per_ppt %>%
  group_by(experiment, phase) %>%
  summarise(
    mean_learning_rate = mean(exp_fit_lambda),
    ci_learning_rate = vector_confint(exp_fit_lambda),
    mean_high = mean(exp_fit_N0),
    ci_high = vector_confint(exp_fit_N0),
    .groups = "drop"
  )

p <- data_per_group %>%
  ggplot(
    aes(x = experiment, y = mean_learning_rate, colour = experiment)
  ) +
  theme_classic() +
  labs(
    x = per_group_x_labs,
    y = "Decay Rate"
  ) +
  # remove all x axis labels
  theme(
    legend.position = "none",
    text = element_text(size = text_size)
  ) +
  # colour legend settings
  guides(
    colour = guide_legend(override.aes = list(alpha = 1))
  ) +
  # set colour palette
  scale_colour_manual(values = pallete_list) +
  scale_fill_manual(
    values = pallete_list
  ) +
  # add horizontal lines
  geom_hline(
    yintercept = c(0, 1), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "solid"
  ) +
  geom_hline(
    yintercept = c(0.25, 0.5, 0.75), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "dashed"
  ) +
  # y-axis scale
  scale_y_continuous(
    # limits = c(-35, 5),
    breaks = c(0, 0.25, 0.5, 0.75, 1),
    labels = c(0, 0.25, 0.5, 0.75, 1)
  ) +
  scale_x_discrete(
    labels = c(0, 0, 0, 0)
  ) +
  # add data points
  geom_beeswarm(
    data = data_per_ppt,
    aes(
      y = exp_fit_lambda
    ),
    alpha = 0.1,
    size = 1
  ) +
  geom_linerange(aes(
    ymin = mean_learning_rate - ci_learning_rate,
    ymax = mean_learning_rate + ci_learning_rate
  ), alpha = 0.5, lwd = 2) +
  geom_point()

# save
if (save_plots) {
  ggsave(
    p,
    filename = "../data/figs/paper_figs/fig3_washout_learning_rates.pdf", device = "pdf",
    height = 2, width = per_group_fig_width
  )
}

p

1.5.1 ANOVA - 3 levels

(temp_ANOVA <- aov_car(
  exp_fit_lambda ~ pert * cue + Error(ppid),
  data_per_ppt,
  include_aov = TRUE
))
Contrasts set to contr.sum for the following variables: pert, cue
Anova Table (Type 3 tests)

Response: exp_fit_lambda
    Effect    df  MSE         F  ges p.value
1     pert 1, 77 0.07 18.48 *** .194   <.001
2      cue 1, 77 0.07      1.07 .014    .304
3 pert:cue 1, 77 0.07      0.47 .006    .496
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘+’ 0.1 ‘ ’ 1
print("Bayes anovas and bayes factors:")
[1] "Bayes anovas and bayes factors:"
print("")
[1] ""
bf <- anovaBF(exp_fit_lambda ~ pert * cue, data = data.frame(data_per_ppt), progress = FALSE)
print(bf)
Bayes factor analysis
--------------
[1] pert                  : 433.4347  ±0%
[2] cue                   : 0.3244278 ±0.02%
[3] pert + cue            : 150.7467  ±2%
[4] pert + cue + pert:cue : 56.55872  ±1.9%

Against denominator:
  Intercept only 
---
Bayes factor type: BFlinearModel, JZS
print(bayesfactor_inclusion(bf))
Inclusion Bayes Factors (Model Averaged)

         P(prior) P(posterior) Inclusion BF
pert         0.60         1.00       322.52
cue          0.60         0.32        0.319
cue:pert     0.20         0.09        0.386

* Compared among: all models
*    Priors odds: uniform-equal
# Note: default multiplicity correction for pairs summary is Tukey HSD
print("----------------------------- EMMs -----------------------------")
[1] "----------------------------- EMMs -----------------------------"
emms_obj <- emmeans(temp_ANOVA, "pert")
NOTE: Results may be misleading due to involvement in interactions
print(pwpm(emms_obj, diffs = FALSE))
        curved   rot30
curved [0.451]  <.0001
rot30          [0.203]

Row and column labels: pert
Upper triangle: P values 
Diagonal: [Estimates] (emmean) 
# Effect size is Cohen's D
eff_size(emms_obj, edf = temp_ANOVA$anova_table$`den Df`[1], sigma = sigma(temp_ANOVA$lm))
 contrast       effect.size    SE df lower.CL upper.CL
 curved - rot30       0.956 0.235 77    0.487     1.42

Results are averaged over the levels of: cue 
sigma used for effect sizes: 0.2602 
Confidence level used: 0.95 
print("----------------------------- Full Tukey HSD -----------------------------")
[1] "----------------------------- Full Tukey HSD -----------------------------"
print(TukeyHSD(temp_ANOVA$aov))
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = tmp_formula, data = dat.ret, contrasts = contrasts)

$pert
                   diff        lwr        upr    p adj
rot30-curved -0.2483742 -0.3635136 -0.1332348 5.03e-05

$cue
                       diff         lwr       upr     p adj
uncued-cued_tilt 0.05932141 -0.05581798 0.1744608 0.3081406

$`pert:cue`
                                        diff         lwr          upr     p adj
rot30:cued_tilt-curved:cued_tilt -0.20908884 -0.42515016  0.006972473 0.0614883
curved:uncued-curved:cued_tilt    0.09933909 -0.11672222  0.315400403 0.6240862
rot30:uncued-curved:cued_tilt    -0.18881487 -0.40228853  0.024658785 0.1017557
curved:uncued-rot30:cued_tilt     0.30842793  0.09236662  0.524489245 0.0019055
rot30:uncued-rot30:cued_tilt      0.02027397 -0.19319969  0.233747627 0.9945085
rot30:uncued-curved:uncued       -0.28815396 -0.50162762 -0.074680304 0.0036829
print(eff_size(emmeans(temp_ANOVA$aov, c("pert", "cue")),
  edf = temp_ANOVA$anova_table$`den Df`[1],
  sigma = sigma(temp_ANOVA$lm)
))
 contrast                           effect.size    SE df lower.CL upper.CL
 curved cued_tilt - rot30 cued_tilt      0.8036 0.323 77   0.1609    1.446
 curved cued_tilt - curved uncued       -0.3818 0.318 77  -1.0145    0.251
 curved cued_tilt - rot30 uncued         0.7257 0.318 77   0.0928    1.359
 rot30 cued_tilt - curved uncued        -1.1854 0.330 77  -1.8432   -0.528
 rot30 cued_tilt - rot30 uncued         -0.0779 0.313 77  -0.7002    0.544
 curved uncued - rot30 uncued            1.1075 0.325 77   0.4605    1.755

sigma used for effect sizes: 0.2602 
Confidence level used: 0.95 

1.6 Washout - Fit High Points (Starts)

p <- data_per_group %>%
  ggplot(
    aes(x = experiment, y = mean_high, colour = experiment)
  ) +
  theme_classic() +
  labs(
    x = per_group_x_labs,
    y = "Start Point of Decay"
  ) +
  # for the colour legend, only show the first 7
  # Note this doesn't work for the plotly plot
  guides(
    colour = guide_legend(override.aes = list(alpha = 1))
  ) +
  # set colour palette
  scale_colour_manual(values = pallete_list) +
  scale_fill_manual(values = pallete_list) +
  # add horizontal lines
  geom_hline(
    yintercept = c(0, 1), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "solid"
  ) +
  geom_hline(
    yintercept = c(0.5, 1.5), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "dashed"
  ) +
  # y-axis scale
  scale_y_continuous(
    limits = c(-0.5, 1.6),
    breaks = c(-0.5, 0, 0.5, 1, 1.5),
    labels = c(-0.5, 0, 0.5, 1, 1.5)
  ) +
  scale_x_discrete(
    labels = c(0, 0, 0, 0)
  ) +
  # remove all x axis labels
  theme(
    legend.position = "none",
    text = element_text(size = text_size)
  ) +
  # add data points
  geom_beeswarm(
    data = data_per_ppt,
    aes(
      y = exp_fit_N0
    ),
    alpha = 0.1,
    size = 1
  ) +
  geom_linerange(aes(
    ymin = mean_high - ci_high,
    ymax = mean_high + ci_high
  ), alpha = 0.5, lwd = 2) +
  geom_point()

# save
if (save_plots) {
  ggsave(
    p,
    filename = "../data/figs/paper_figs/fig3_washout_starts.pdf", device = "pdf",
    height = 2, width = per_group_fig_width
  )
}

p

1.6.1 ANOVA - 3 levels

(temp_ANOVA <- aov_car(
  exp_fit_N0 ~ pert * cue + Error(ppid),
  data_per_ppt,
  include_aov = TRUE
))
Contrasts set to contr.sum for the following variables: pert, cue
Anova Table (Type 3 tests)

Response: exp_fit_N0
    Effect    df  MSE         F  ges p.value
1     pert 1, 77 0.11 16.20 *** .174   <.001
2      cue 1, 77 0.11 18.31 *** .192   <.001
3 pert:cue 1, 77 0.11      0.83 .011    .364
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘+’ 0.1 ‘ ’ 1
print("Bayes anovas and bayes factors:")
[1] "Bayes anovas and bayes factors:"
print("")
[1] ""
bf <- anovaBF(exp_fit_N0 ~ pert * cue, data = data.frame(data_per_ppt), progress = FALSE)
print(bf)
Bayes factor analysis
--------------
[1] pert                  : 67.83776 ±0%
[2] cue                   : 151.9825 ±0%
[3] pert + cue            : 27387.72 ±2.26%
[4] pert + cue + pert:cue : 11973.49 ±0.94%

Against denominator:
  Intercept only 
---
Bayes factor type: BFlinearModel, JZS
print(bayesfactor_inclusion(bf))
Inclusion Bayes Factors (Model Averaged)

         P(prior) P(posterior) Inclusion BF
pert         0.60         1.00       171.82
cue          0.60         1.00       382.67
cue:pert     0.20         0.30         1.73

* Compared among: all models
*    Priors odds: uniform-equal
# Note: default multiplicity correction for pairs summary is Tukey HSD
print("----------------------------- EMMs -----------------------------")
[1] "----------------------------- EMMs -----------------------------"
emms_obj <- emmeans(temp_ANOVA, "pert")
NOTE: Results may be misleading due to involvement in interactions
print(pwpm(emms_obj, diffs = FALSE))
        curved   rot30
curved [0.527]  0.0001
rot30          [0.825]

Row and column labels: pert
Upper triangle: P values 
Diagonal: [Estimates] (emmean) 
# Effect size is Cohen's D
eff_size(emms_obj, edf = temp_ANOVA$anova_table$`den Df`[1], sigma = sigma(temp_ANOVA$lm))
 contrast       effect.size    SE df lower.CL upper.CL
 curved - rot30      -0.895 0.234 77    -1.36   -0.429

Results are averaged over the levels of: cue 
sigma used for effect sizes: 0.333 
Confidence level used: 0.95 
print("----------------------------- Full Tukey HSD -----------------------------")
[1] "----------------------------- Full Tukey HSD -----------------------------"
print(TukeyHSD(temp_ANOVA$aov))
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = tmp_formula, data = dat.ret, contrasts = contrasts)

$pert
                  diff       lwr       upr     p adj
rot30-curved 0.3026107 0.1552576 0.4499637 0.0001054

$cue
                      diff       lwr       upr    p adj
uncued-cued_tilt 0.3174539 0.1701009 0.4648069 5.14e-05

$`pert:cue`
                                       diff         lwr       upr     p adj
rot30:cued_tilt-curved:cued_tilt 0.23030409 -0.04620673 0.5068149 0.1359571
curved:uncued-curved:cued_tilt   0.24906650 -0.02744432 0.5255773 0.0925397
rot30:uncued-curved:cued_tilt    0.61461041  0.34141122 0.8878096 0.0000005
curved:uncued-rot30:cued_tilt    0.01876241 -0.25774841 0.2952732 0.9979734
rot30:uncued-rot30:cued_tilt     0.38430632  0.11110712 0.6575055 0.0022792
rot30:uncued-curved:uncued       0.36554391  0.09234471 0.6387431 0.0040622
print(eff_size(emmeans(temp_ANOVA$aov, c("pert", "cue")),
  edf = temp_ANOVA$anova_table$`den Df`[1],
  sigma = sigma(temp_ANOVA$lm)
))
 contrast                           effect.size    SE df lower.CL upper.CL
 curved cued_tilt - rot30 cued_tilt     -0.6917 0.321 77   -1.331  -0.0523
 curved cued_tilt - curved uncued       -0.7480 0.322 77   -1.389  -0.1070
 curved cued_tilt - rot30 uncued        -1.8458 0.346 77   -2.535  -1.1568
 rot30 cued_tilt - curved uncued        -0.0563 0.316 77   -0.686   0.5734
 rot30 cued_tilt - rot30 uncued         -1.1542 0.326 77   -1.803  -0.5050
 curved uncued - rot30 uncued           -1.0978 0.325 77   -1.744  -0.4512

sigma used for effect sizes: 0.333 
Confidence level used: 0.95 

2 Alternate Washout Phases

These include the last trial of the Training phase for all Cued conditions.

2.1 Normalized Washout Phases

# rest of the exps
data_per_group <- omnibus_df %>%
  filter(
    experiment %in% c(
      "rot30_cued_tilt", "rot30_uncued",
      "curved_cued_tilt", "curved_uncued"
    ),
    trial_num >= 214,
    alt_washout_block == TRUE,
  ) %>%
  arrange(experiment, ppid, trial_num) %>%
  group_by(experiment, trial_num) %>%
  summarise(
    mean_deviation = mean(norm_throw_deviation),
    ci_deviation = vector_confint(norm_throw_deviation),
    .groups = "drop"
  )

# NOTE: this can't be combined with above since we are using nrow
data_per_group <- data_per_group %>%
  mutate(dummy_x = rep(1:40,
    length.out = nrow(data_per_group)
  ))

# add a dummy column with repeating sequence


# set up plot
p <- data_per_group %>%
  ggplot(
    aes(
      x = dummy_x, y = mean_deviation, colour = experiment
    )
  ) +
  theme_classic() +
  theme(
    legend.position = "none",
    text = element_text(size = text_size)
  ) +
  labs(
    x = "Trial",
    y = "Normalized Throw Angle"
  ) +
  # add horizontal lines
  geom_hline(
    yintercept = c(0, 1), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "solid"
  ) +
  geom_hline(
    yintercept = c(0.5, 1.5), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "dashed"
  ) +
  # set colour palette
  scale_colour_manual(values = pallete_list) +
  scale_fill_manual(values = pallete_list) + # scale axes
  scale_y_continuous(
    breaks = c(0, 0.5, 1, 1.5),
    labels = c(0, 0.5, 1, 1.5)
  ) +
  scale_x_continuous(
    breaks = curve_x_breaks,
    labels = curve_x_breaks
  )

# add confidence intervals and data points
for (uniq_exp in unique(data_per_group$experiment)) {
  # get the data for this block
  to_plot_data <- filter(data_per_group, experiment == uniq_exp)

  p <- p + geom_ribbon(
    data = to_plot_data,
    aes(
      ymin = mean_deviation - ci_deviation,
      ymax = mean_deviation + ci_deviation,
      fill = experiment
    ), colour = NA, alpha = 0.3
  ) + geom_line(
    data = to_plot_data
  )
}

# save
if (save_plots) {
  ggsave(
    p,
    filename = "../data/figs/paper_figs/fig3_curved_alt_washout.pdf", device = "pdf",
    height = 2, width = 2.5
  )
}

p

# ggplotly(p)
fitted_data <- fitted_alt_washout_df %>%
  filter(
    experiment %in% c(
      "rot30_cued_tilt", "rot30_uncued",
      "curved_cued_tilt", "curved_uncued"
    ),
    phase == "washout"
  ) %>%
  mutate(
    pert = factor(str_split_fixed(experiment, "_", 2)[, 1]),
    cue = factor(str_split_fixed(experiment, "_", 2)[, 2])
  )

p <- fitted_data %>%
  ggplot(
    aes(x = x + 1, y = y, colour = experiment)
  ) +
  theme_classic() +
  theme(
    legend.position = "none",
    text = element_text(size = text_size)
  ) +
  labs(
    x = "Trial",
    y = "Normalized Throw Angle"
  ) +
  # add horizontal lines
  geom_hline(
    yintercept = c(0, 1), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "solid"
  ) +
  geom_hline(
    yintercept = c(0.5, 1.5), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "dashed"
  ) +
  # set colour palette
  scale_colour_manual(values = pallete_list) +
  scale_fill_manual(values = pallete_list) + # scale axes
  scale_y_continuous(
    breaks = c(0, 0.5, 1, 1.5),
    labels = c(0, 0.5, 1, 1.5),
    limits = c(-0.25, 1.5)
  ) +
  scale_x_continuous(
    breaks = curve_x_breaks,
    labels = curve_x_breaks
  ) +
  geom_line()

# save
if (save_plots) {
  ggsave(
    p,
    filename = "../data/figs/paper_figs/fig3_curved_alt_washout_fitted_only.pdf", device = "pdf",
    height = 2, width = curve_fig_width
  )
}

p

2.2 Washout - Fit Learning Rates

data_per_ppt <- alt_washout_rates %>%
  filter(
    experiment %in% c(
      # "accel_cued_tilt", "accel_uncued",
      "rot30_cued_tilt", "rot30_uncued",
      "curved_cued_tilt", "curved_uncued"
    )
  ) %>%
  mutate(
    pert = factor(str_split_fixed(experiment, "_", 2)[, 1]),
    cue = factor(str_split_fixed(experiment, "_", 2)[, 2]),
    ppid = factor(ppid)
  )

data_per_group <- data_per_ppt %>%
  group_by(experiment) %>%
  summarise(
    mean_learning_rate = mean(exp_fit_lambda),
    ci_learning_rate = vector_confint(exp_fit_lambda),
    mean_high = mean(exp_fit_N0),
    ci_high = vector_confint(exp_fit_N0),
    .groups = "drop"
  )

p <- data_per_group %>%
  ggplot(
    aes(x = experiment, y = mean_learning_rate, colour = experiment)
  ) +
  theme_classic() +
  labs(
    x = per_group_x_labs,
    y = "Decay Rate"
  ) +
  # remove all x axis labels
  theme(
    legend.position = "none",
    text = element_text(size = text_size)
  ) +
  # colour legend settings
  guides(
    colour = guide_legend(override.aes = list(alpha = 1))
  ) +
  # set colour palette
  scale_colour_manual(values = pallete_list) +
  scale_fill_manual(
    values = pallete_list
  ) +
  # add horizontal lines
  geom_hline(
    yintercept = c(0, 1), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "solid"
  ) +
  geom_hline(
    yintercept = c(0.25, 0.5, 0.75), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "dashed"
  ) +
  # y-axis scale
  scale_y_continuous(
    # limits = c(-35, 5),
    breaks = c(0, 0.25, 0.5, 0.75, 1),
    labels = c(0, 0.25, 0.5, 0.75, 1)
  ) +
  scale_x_discrete(
    labels = c(0, 0, 0, 0)
  ) +
  # add data points
  geom_beeswarm(
    data = data_per_ppt,
    aes(
      y = exp_fit_lambda
    ),
    alpha = 0.1,
    size = 1
  ) +
  geom_linerange(aes(
    ymin = mean_learning_rate - ci_learning_rate,
    ymax = mean_learning_rate + ci_learning_rate
  ), alpha = 0.5, lwd = 2) +
  geom_point()

# save
if (save_plots) {
  ggsave(
    p,
    filename = "../data/figs/paper_figs/fig3_curved_alt_washout_learning_rates.pdf", device = "pdf",
    height = 2, width = per_group_fig_width
  )
}

p

(temp_ANOVA <- aov_car(
  exp_fit_lambda ~ pert * cue + Error(ppid),
  data_per_ppt,
  include_aov = TRUE
))
Contrasts set to contr.sum for the following variables: pert, cue
Anova Table (Type 3 tests)

Response: exp_fit_lambda
    Effect    df  MSE         F  ges p.value
1     pert 1, 77 0.05 44.94 *** .369   <.001
2      cue 1, 77 0.05      1.02 .013    .316
3 pert:cue 1, 77 0.05      0.58 .008    .447
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘+’ 0.1 ‘ ’ 1
print("Bayes anovas and bayes factors:")
[1] "Bayes anovas and bayes factors:"
print("")
[1] ""
bf <- anovaBF(exp_fit_lambda ~ pert * cue, data = data.frame(data_per_ppt), progress = FALSE)
print(bf)
Bayes factor analysis
--------------
[1] pert                  : 3524431   ±0%
[2] cue                   : 0.3210555 ±0.02%
[3] pert + cue            : 1199871   ±1.22%
[4] pert + cue + pert:cue : 487221.8  ±1.3%

Against denominator:
  Intercept only 
---
Bayes factor type: BFlinearModel, JZS
print(bayesfactor_inclusion(bf))
Inclusion Bayes Factors (Model Averaged)

         P(prior) P(posterior) Inclusion BF
pert         0.60         1.00     2.63e+06
cue          0.60         0.32        0.319
cue:pert     0.20         0.09        0.413

* Compared among: all models
*    Priors odds: uniform-equal

Pairwise comparisons:

# posthoc tests
# (m1 <- emmeans(temp_ANOVA, ~pert))
# print("Pairwise comparisons:")
# print(summary(pairs(m1), adjust = "tukey")) # Note: default multiplicity correction for pairs summary is Tukey HSD

# Note: default multiplicity correction for pairs summary is Tukey HSD
print("-------------------------- EMMs cue --------------------------")
[1] "-------------------------- EMMs cue --------------------------"
emms_obj <- emmeans(temp_ANOVA, "cue")
NOTE: Results may be misleading due to involvement in interactions
print(pwpm(emms_obj, diffs = FALSE))
          cued_tilt  uncued
cued_tilt   [0.406]  0.3159
uncued              [0.357]

Row and column labels: cue
Upper triangle: P values 
Diagonal: [Estimates] (emmean) 
# Effect size is Cohen's D
eff_size(emms_obj, edf = temp_ANOVA$anova_table$`den Df`[1], sigma = sigma(temp_ANOVA$lm))
 contrast           effect.size    SE df lower.CL upper.CL
 cued_tilt - uncued       0.224 0.223 77    -0.22    0.668

Results are averaged over the levels of: pert 
sigma used for effect sizes: 0.2183 
Confidence level used: 0.95 
print("-------------------------- EMMs perts --------------------------")
[1] "-------------------------- EMMs perts --------------------------"
emms_obj <- emmeans(temp_ANOVA, "pert")
NOTE: Results may be misleading due to involvement in interactions
print(pwpm(emms_obj, diffs = FALSE))
        curved   rot30
curved [0.544]  <.0001
rot30          [0.219]

Row and column labels: pert
Upper triangle: P values 
Diagonal: [Estimates] (emmean) 
# Effect size is Cohen's D
eff_size(emms_obj, edf = temp_ANOVA$anova_table$`den Df`[1], sigma = sigma(temp_ANOVA$lm))
 contrast       effect.size    SE df lower.CL upper.CL
 curved - rot30        1.49 0.253 77    0.987     1.99

Results are averaged over the levels of: cue 
sigma used for effect sizes: 0.2183 
Confidence level used: 0.95 
print("----------------------------- Full Tukey HSD -----------------------------")
[1] "----------------------------- Full Tukey HSD -----------------------------"
print(TukeyHSD(temp_ANOVA$aov))
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = tmp_formula, data = dat.ret, contrasts = contrasts)

$pert
                   diff        lwr        upr p adj
rot30-curved -0.3254002 -0.4219955 -0.2288049     0

$cue
                        diff        lwr        upr     p adj
uncued-cued_tilt -0.04852349 -0.1451188 0.04807182 0.3203069

$`pert:cue`
                                        diff         lwr         upr     p adj
rot30:cued_tilt-curved:cued_tilt -0.36235677 -0.54361976 -0.18109378 0.0000077
curved:uncued-curved:cued_tilt   -0.08607912 -0.26734211  0.09518387 0.5991191
rot30:uncued-curved:cued_tilt    -0.37423308 -0.55332518 -0.19514099 0.0000030
curved:uncued-rot30:cued_tilt     0.27627765  0.09501466  0.45754064 0.0008105
rot30:uncued-rot30:cued_tilt     -0.01187631 -0.19096841  0.16721578 0.9981073
rot30:uncued-curved:uncued       -0.28815396 -0.46724606 -0.10906187 0.0003720
print(eff_size(emmeans(temp_ANOVA$aov, c("pert", "cue")),
  edf = temp_ANOVA$anova_table$`den Df`[1],
  sigma = sigma(temp_ANOVA$lm)
))
 contrast                           effect.size    SE df lower.CL upper.CL
 curved cued_tilt - rot30 cued_tilt      1.6601 0.343 77    0.976    2.344
 curved cued_tilt - curved uncued        0.3944 0.318 77   -0.239    1.027
 curved cued_tilt - rot30 uncued         1.7145 0.342 77    1.034    2.395
 rot30 cued_tilt - curved uncued        -1.2657 0.332 77   -1.927   -0.604
 rot30 cued_tilt - rot30 uncued          0.0544 0.312 77   -0.568    0.677
 curved uncued - rot30 uncued            1.3201 0.330 77    0.663    1.977

sigma used for effect sizes: 0.2183 
Confidence level used: 0.95 

2.3 Washout - Fit High Points (Starts)

p <- data_per_group %>%
  ggplot(
    aes(x = experiment, y = mean_high, colour = experiment)
  ) +
  theme_classic() +
  labs(
    x = per_group_x_labs,
    y = "Start Point of Decay"
  ) +
  # for the colour legend, only show the first 7
  # Note this doesn't work for the plotly plot
  guides(
    colour = guide_legend(override.aes = list(alpha = 1))
  ) +
  # set colour palette
  scale_colour_manual(values = pallete_list) +
  scale_fill_manual(values = pallete_list) +
  # add horizontal lines
  geom_hline(
    yintercept = c(0, 1), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "solid"
  ) +
  geom_hline(
    yintercept = c(0.5, 1.5), linewidth = 0.4,
    colour = "#CCCCCC", linetype = "dashed"
  ) +
  # y-axis scale
  scale_y_continuous(
    limits = c(-0.5, 1.6),
    breaks = c(-0.5, 0, 0.5, 1, 1.5),
    labels = c(-0.5, 0, 0.5, 1, 1.5)
  ) +
  scale_x_discrete(
    labels = c(0, 0, 0, 0)
  ) +
  # remove all x axis labels
  theme(
    legend.position = "none",
    text = element_text(size = text_size)
  ) +
  # add data points
  geom_beeswarm(
    data = data_per_ppt,
    aes(
      y = exp_fit_N0
    ),
    alpha = 0.1,
    size = 1
  ) +
  geom_linerange(aes(
    ymin = mean_high - ci_high,
    ymax = mean_high + ci_high
  ), alpha = 0.5, lwd = 2) +
  geom_point()

# save
if (save_plots) {
  ggsave(
    p,
    filename = "../data/figs/paper_figs/fig3_curved_alt_washout_starts.pdf", device = "pdf",
    height = 2, width = per_group_fig_width
  )
}

p

(temp_ANOVA <- aov_car(
  exp_fit_N0 ~ pert * cue + Error(ppid),
  data_per_ppt,
  include_aov = TRUE
))
Contrasts set to contr.sum for the following variables: pert, cue
Anova Table (Type 3 tests)

Response: exp_fit_N0
    Effect    df  MSE      F  ges p.value
1     pert 1, 77 0.14 3.73 + .046    .057
2      cue 1, 77 0.14   2.58 .032    .112
3 pert:cue 1, 77 0.14 6.10 * .073    .016
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘+’ 0.1 ‘ ’ 1
print("Bayes anovas and bayes factors:")
[1] "Bayes anovas and bayes factors:"
print("")
[1] ""
bf <- anovaBF(exp_fit_N0 ~ pert * cue, data = data.frame(data_per_ppt), progress = FALSE)
print(bf)
Bayes factor analysis
--------------
[1] pert                  : 1.034682  ±0.01%
[2] cue                   : 0.5958974 ±0.01%
[3] pert + cue            : 0.6489424 ±1.85%
[4] pert + cue + pert:cue : 2.308289  ±1%

Against denominator:
  Intercept only 
---
Bayes factor type: BFlinearModel, JZS
print(bayesfactor_inclusion(bf))
Inclusion Bayes Factors (Model Averaged)

         P(prior) P(posterior) Inclusion BF
pert         0.60         0.71         1.67
cue          0.60         0.64         1.16
cue:pert     0.20         0.41         2.82

* Compared among: all models
*    Priors odds: uniform-equal

Pairwise comparisons:

# posthoc tests
# (m1 <- emmeans(temp_ANOVA, ~pert))
# print("Pairwise comparisons:")
# print(summary(pairs(m1), adjust = "tukey")) # Note: default multiplicity correction for pairs summary is Tukey HSD

# Note: default multiplicity correction for pairs summary is Tukey HSD
print("-------------------------- EMMs cue --------------------------")
[1] "-------------------------- EMMs cue --------------------------"
emms_obj <- emmeans(temp_ANOVA, "cue")
NOTE: Results may be misleading due to involvement in interactions
print(pwpm(emms_obj, diffs = FALSE))
          cued_tilt  uncued
cued_tilt   [0.967]  0.1125
uncued              [0.834]

Row and column labels: cue
Upper triangle: P values 
Diagonal: [Estimates] (emmean) 
# Effect size is Cohen's D
eff_size(emms_obj, edf = temp_ANOVA$anova_table$`den Df`[1], sigma = sigma(temp_ANOVA$lm))
 contrast           effect.size    SE df lower.CL upper.CL
 cued_tilt - uncued       0.357 0.224 77  -0.0895    0.803

Results are averaged over the levels of: pert 
sigma used for effect sizes: 0.3737 
Confidence level used: 0.95 
print("-------------------------- EMMs perts --------------------------")
[1] "-------------------------- EMMs perts --------------------------"
emms_obj <- emmeans(temp_ANOVA, "pert")
NOTE: Results may be misleading due to involvement in interactions
print(pwpm(emms_obj, diffs = FALSE))
        curved   rot30
curved [0.821]  0.0572
rot30          [0.981]

Row and column labels: pert
Upper triangle: P values 
Diagonal: [Estimates] (emmean) 
# Effect size is Cohen's D
eff_size(emms_obj, edf = temp_ANOVA$anova_table$`den Df`[1], sigma = sigma(temp_ANOVA$lm))
 contrast       effect.size    SE df lower.CL upper.CL
 curved - rot30      -0.429 0.225 77   -0.877   0.0188

Results are averaged over the levels of: cue 
sigma used for effect sizes: 0.3737 
Confidence level used: 0.95 
print("----------------------------- Full Tukey HSD -----------------------------")
[1] "----------------------------- Full Tukey HSD -----------------------------"
print(TukeyHSD(temp_ANOVA$aov))
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = tmp_formula, data = dat.ret, contrasts = contrasts)

$pert
                  diff          lwr       upr     p adj
rot30-curved 0.1612721 -0.004120548 0.3266647 0.0558383

$cue
                       diff        lwr        upr     p adj
uncued-cued_tilt -0.1308731 -0.2962657 0.03451958 0.1192056

$`pert:cue`
                                        diff         lwr         upr     p adj
rot30:cued_tilt-curved:cued_tilt -0.04475055 -0.35511304  0.26561194 0.9813751
curved:uncued-curved:cued_tilt   -0.33851140 -0.64887390 -0.02814891 0.0270589
rot30:uncued-curved:cued_tilt     0.02703251 -0.27961294  0.33367795 0.9955934
curved:uncued-rot30:cued_tilt    -0.29376085 -0.60412335  0.01660164 0.0702030
rot30:uncued-rot30:cued_tilt      0.07178306 -0.23486239  0.37842850 0.9270944
rot30:uncued-curved:uncued        0.36554391  0.05889847  0.67218935 0.0129087
print(eff_size(emmeans(temp_ANOVA$aov, c("pert", "cue")),
  edf = temp_ANOVA$anova_table$`den Df`[1],
  sigma = sigma(temp_ANOVA$lm)
))
 contrast                           effect.size    SE df lower.CL upper.CL
 curved cued_tilt - rot30 cued_tilt      0.1197 0.316 77   -0.510    0.750
 curved cued_tilt - curved uncued        0.9057 0.325 77    0.259    1.552
 curved cued_tilt - rot30 uncued        -0.0723 0.312 77   -0.695    0.550
 rot30 cued_tilt - curved uncued         0.7860 0.323 77    0.144    1.428
 rot30 cued_tilt - rot30 uncued         -0.1921 0.313 77   -0.815    0.431
 curved uncued - rot30 uncued           -0.9781 0.322 77   -1.620   -0.336

sigma used for effect sizes: 0.3737 
Confidence level used: 0.95 
LS0tDQp0aXRsZTogIkJpbGxpYXJkcyBhbmQgVGlsdHMgQW5hbHlzaXMgTm90ZWJvb2siDQphdXRob3I6ICJTaGFuYWF0aGFuYW4gTW9kY2hhbGluZ2FtIg0Kb3V0cHV0OiANCiAgaHRtbF9ub3RlYm9vazoNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUNCiAgICBkZl9wcmludDogcGFnZWQNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCi0tLQ0KDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KIyBjbGVhbiBlbnZpcm9ubWVudA0Kcm0obGlzdCA9IGxzKCkpDQojIHNldCBzZWVkDQpzZXQuc2VlZCgxMjM0KQ0KDQpzb3VyY2UoIi4uL3NyYy9oZWxwZXJfZnVuY3MuUiIpDQpzb3VyY2UoIi4uL3NjcmlwdHMvZmlndXJlX2Z1bmNzLlIiKQ0KbGlicmFyeShkYXRhLnRhYmxlKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGdnYmVlc3dhcm0pDQoNCiMgZm9yIHN0YXRpc3RpY3MNCmxpYnJhcnkoZXopICMgZm9yIEFOT1ZBcw0KbGlicmFyeShhZmV4KSAjIGZvciBBTk9WQXMNCmxpYnJhcnkoZW1tZWFucykNCmxpYnJhcnkoZWZmZWN0c2l6ZSkgIyBmb3IgZXRhLXNxdWFyZWQNCmxpYnJhcnkoQmF5ZXNGYWN0b3IpDQpsaWJyYXJ5KGJheWVzdGVzdFIpDQoNCmxpYnJhcnkoZnVycnIpDQpwbGFuKG11bHRpc2Vzc2lvbikNCg0Kb3B0aW9ucyhkcGx5ci5zdW1tYXJpc2UuaW5mb3JtID0gRkFMU0UpDQoNCiMgdmFycw0Kb21uaWJ1c19wYXRoIDwtICIuLi9kYXRhL3Byb2Nlc3NlZC9vbW5pYnVzL29tbmlidXNfcmF3LmNzdiINCg0KbnVtX2V4cHMgPC0gNw0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShwbG90bHkpDQpgYGANCg0KDQojIyBMb2FkIGFsbCBvZiB0aGUgdGhyb3cgZGF0YQ0KYGBge3J9DQojIE5vdGU6IHRoaXMgbm90ZWJvb2sgcmlnaHQgbm93IFJFUVVJUkVTIHRoYXQgdGhlIGFuYWx5c2lzIG5vdGVib29rIGJlIHJ1biB0bw0KIyBtYWtlIHRoZSBmaXRzLCBvciB0aGF0IHRoZSBkYXRhIGZvbGRlciBjb250YWlucyB0aGUgZml0cw0KDQojIGxvYWQgb21uaWJ1cyBkYXRhZnJhbWUNCm9tbmlidXNfZGYgPC0gcmVhZF9kZWxpbSgiLi4vZGF0YS9wcm9jZXNzZWQvb21uaWJ1cy9vbW5pYnVzX3Jhdy5jc3YiLA0KICBkZWxpbSA9ICIsIiwNCiAgY29sX3R5cGVzID0gY29scygNCiAgICAuZGVmYXVsdCA9IGNvbF9kb3VibGUoKSwNCiAgICB0eXBlID0gY29sX2ZhY3RvcigpLA0KICAgIHBwaWQgPSBjb2xfZmFjdG9yKCksDQogICAgZXhwX2xhYmVsID0gY29sX2ZhY3RvcigpLA0KICAgIGV4cGVyaW1lbnQgPSBjb2xfZmFjdG9yKCksDQogICAgaGFuZCA9IGNvbF9mYWN0b3IoKSwNCiAgICBjYW1lcmFfdGlsdCA9IGNvbF9mYWN0b3IoKSwNCiAgICBzdXJmYWNlX3RpbHQgPSBjb2xfZmFjdG9yKCksDQogICAgdGFyZ2V0ID0gY29sX2ZhY3RvcigpLA0KICAgIHRlc3RfdHlwZSA9IGNvbF9mYWN0b3IoKSwNCiAgICBwaGFzZSA9IGNvbF9mYWN0b3IoKSwNCiAgICBsZWFybmluZ19hbmRfZGVjYXlfY3VydmVzID0gY29sX2ZhY3RvcigpLA0KICAgIHByaW9yX2FuaW0gPSBjb2xfZmFjdG9yKCksDQogICAgYmFzZWxpbmVfYmxvY2sgPSBjb2xfbG9naWNhbCgpLA0KICAgIGFsdF93YXNob3V0X2Jsb2NrID0gY29sX2xvZ2ljYWwoKSwNCiAgICBhbHRfYWxsX3dhc2hvdXRfYmxvY2sgPSBjb2xfbG9naWNhbCgpLA0KICAgIHRhc2tfdHlwZSA9IGNvbF9mYWN0b3IoKSwNCiAgICBzdXJmYWNlID0gY29sX2ZhY3RvcigpLA0KICAgIGFuaW1fdHlwZSA9IGNvbF9mYWN0b3IoKQ0KICApDQopICU+JSAjIGZpbHRlciBvdXQgcHJhY3RpY2UgYmxvY2tzDQogIGZpbHRlcigNCiAgICBibG9ja19udW0gPiA0LA0KICAgICEocHBpZCAlaW4lIGMoMiwgODEsIDgyLCA4MykpDQogICkNCg0KIyBsb2FkIGV4cG9uZW50aWFsIGRlY2F5IGZpdHMNCmluaXRfbGVhcm5pbmdfcmF0ZXMgPC0gcmVhZF9jc3YoDQogICIuLi9kYXRhL3Byb2Nlc3NlZC9sZWFybmluZ19yYXRlX2RmLmNzdiIsDQogIGNvbF90eXBlcyA9IGNvbHMoDQogICAgLmRlZmF1bHQgPSBjb2xfZG91YmxlKCksDQogICAgZXhwZXJpbWVudCA9IGNvbF9mYWN0b3IoKSwNCiAgICBwaGFzZSA9IGNvbF9mYWN0b3IoKQ0KICApDQopICU+JQ0KICBtdXRhdGUoZXhwZXJpbWVudCA9IGZhY3RvcigNCiAgICBleHBlcmltZW50LA0KICAgIGxldmVscyA9IGMoDQogICAgICAiYWNjZWxfY3VlZF90aWx0IiwgImFjY2VsX3VuY3VlZCIsDQogICAgICAiY3VydmVkX2N1ZWRfdGlsdCIsICJjdXJ2ZWRfdW5jdWVkIiwNCiAgICAgICJyb3QzMF9jdWVkX3RpbHQiLCAicm90MzBfdW5jdWVkIiwNCiAgICAgICJyb3QxNV9jdWVkX3RpbHQiLCAicm90MTVfdW5jdWVkIiwNCiAgICAgICJhX2JhbGxfcm9sbF9hbmltYXRlX3N1cmZhY2UiDQogICAgKQ0KICApKQ0KDQppbml0X2xlYXJuaW5nX3JhdGVzXzNwYXIgPC0gcmVhZF9jc3YoDQogICIuLi9kYXRhL3Byb2Nlc3NlZC9sZWFybmluZ19yYXRlX2RmXzNwYXIuY3N2IiwNCiAgY29sX3R5cGVzID0gY29scygNCiAgICAuZGVmYXVsdCA9IGNvbF9kb3VibGUoKSwNCiAgICBleHBlcmltZW50ID0gY29sX2ZhY3RvcigpLA0KICAgIHBoYXNlID0gY29sX2ZhY3RvcigpDQogICkNCikgJT4lDQogIG11dGF0ZShleHBlcmltZW50ID0gZmFjdG9yKA0KICAgIGV4cGVyaW1lbnQsDQogICAgbGV2ZWxzID0gYygNCiAgICAgICJhY2NlbF9jdWVkX3RpbHQiLCAiYWNjZWxfdW5jdWVkIiwNCiAgICAgICJjdXJ2ZWRfY3VlZF90aWx0IiwgImN1cnZlZF91bmN1ZWQiLA0KICAgICAgInJvdDMwX2N1ZWRfdGlsdCIsICJyb3QzMF91bmN1ZWQiLA0KICAgICAgInJvdDE1X2N1ZWRfdGlsdCIsICJyb3QxNV91bmN1ZWQiLA0KICAgICAgImFfYmFsbF9yb2xsX2FuaW1hdGVfc3VyZmFjZSINCiAgICApDQogICkpDQoNCmFuaW1fbGVhcm5pbmdfcmF0ZXMgPC0gcmVhZF9jc3YoDQogICIuLi9kYXRhL3Byb2Nlc3NlZC9sZWFybmluZ19yYXRlX2RmX2FuaW0uY3N2IiwNCiAgY29sX3R5cGVzID0gY29scygNCiAgICAuZGVmYXVsdCA9IGNvbF9kb3VibGUoKSwNCiAgICBwcGlkID0gY29sX2ZhY3RvcigpLA0KICAgIGV4cGVyaW1lbnQgPSBjb2xfZmFjdG9yKCksDQogICAgcGhhc2UgPSBjb2xfZmFjdG9yKCkNCiAgKQ0KKSAlPiUNCiAgbXV0YXRlKGV4cGVyaW1lbnQgPSBmYWN0b3IoDQogICAgZXhwZXJpbWVudCwNCiAgICBsZXZlbHMgPSBjKA0KICAgICAgInJvdDMwX2N1ZWRfdGlsdCIsICJyb3QzMF91bmN1ZWQiLA0KICAgICAgImhhbGZfYW5pbSIsICJmdWxsX2FuaW0iDQogICAgKQ0KICApKQ0KDQphbHRfd2FzaG91dF9yYXRlcyA8LSByZWFkX2NzdigNCiAgIi4uL2RhdGEvcHJvY2Vzc2VkL2V4cF9maXRzX2FsdF93YXNob3V0X2N1cnZlcy5jc3YiLA0KICBjb2xfdHlwZXMgPSBjb2xzKA0KICAgIC5kZWZhdWx0ID0gY29sX2RvdWJsZSgpLA0KICAgIGV4cGVyaW1lbnQgPSBjb2xfZmFjdG9yKCksDQogICAgcGhhc2UgPSBjb2xfZmFjdG9yKCkNCiAgICApDQogICkgJT4lDQogIG11dGF0ZShleHBlcmltZW50ID0gZmFjdG9yKA0KICAgIGV4cGVyaW1lbnQsIA0KICAgIGxldmVscyA9IGMoDQogICAgICAiYWNjZWxfY3VlZF90aWx0IiwgImFjY2VsX3VuY3VlZCIsDQogICAgICAiY3VydmVkX2N1ZWRfdGlsdCIsICJjdXJ2ZWRfdW5jdWVkIiwNCiAgICAgICJyb3QzMF9jdWVkX3RpbHQiLCAicm90MzBfdW5jdWVkIiwNCiAgICAgICJyb3QxNV9jdWVkX3RpbHQiLCAicm90MTVfdW5jdWVkIiwNCiAgICAgICJhX2JhbGxfcm9sbF9hbmltYXRlX3N1cmZhY2UiDQogICAgICApDQogICAgKQ0KICApDQoNCmZpdHRlZF9sZWFybmluZ19yYXRlX2RmIDwtIHJlYWRfY3N2KA0KICAiLi4vZGF0YS9wcm9jZXNzZWQvZml0X2N1cnZlcy9maXR0ZWRfbGVhcm5pbmdfcmF0ZV9kZi5jc3YiLA0KICBjb2xfdHlwZXMgPSBjb2xzKA0KICAgIC5kZWZhdWx0ID0gY29sX2RvdWJsZSgpLA0KICAgIGV4cGVyaW1lbnQgPSBjb2xfZmFjdG9yKCksDQogICAgcGhhc2UgPSBjb2xfZmFjdG9yKCkNCiAgKQ0KKSAlPiUNCiAgbXV0YXRlKGV4cGVyaW1lbnQgPSBmYWN0b3IoDQogICAgZXhwZXJpbWVudCwNCiAgICBsZXZlbHMgPSBjKA0KICAgICAgImFjY2VsX2N1ZWRfdGlsdCIsICJhY2NlbF91bmN1ZWQiLA0KICAgICAgImN1cnZlZF9jdWVkX3RpbHQiLCAiY3VydmVkX3VuY3VlZCIsDQogICAgICAicm90MzBfY3VlZF90aWx0IiwgInJvdDMwX3VuY3VlZCIsDQogICAgICAicm90MTVfY3VlZF90aWx0IiwgInJvdDE1X3VuY3VlZCIsDQogICAgICAiYV9iYWxsX3JvbGxfYW5pbWF0ZV9zdXJmYWNlIg0KICAgICkNCiAgKSkNCg0KZml0dGVkX2FsdF93YXNob3V0X2RmIDwtIHJlYWRfY3N2KA0KICAiLi4vZGF0YS9wcm9jZXNzZWQvZml0X2N1cnZlcy9maXR0ZWRfZXhwX2ZpdHNfYWx0X3dhc2hvdXRfY3VydmVzLmNzdiIsDQogIGNvbF90eXBlcyA9IGNvbHMoDQogICAgLmRlZmF1bHQgPSBjb2xfZG91YmxlKCksDQogICAgZXhwZXJpbWVudCA9IGNvbF9mYWN0b3IoKSwNCiAgICBwaGFzZSA9IGNvbF9mYWN0b3IoKQ0KICApDQopICU+JQ0KICBtdXRhdGUoZXhwZXJpbWVudCA9IGZhY3RvcigNCiAgICBleHBlcmltZW50LA0KICAgIGxldmVscyA9IGMoDQogICAgICAiYWNjZWxfY3VlZF90aWx0IiwgImFjY2VsX3VuY3VlZCIsDQogICAgICAiY3VydmVkX2N1ZWRfdGlsdCIsICJjdXJ2ZWRfdW5jdWVkIiwNCiAgICAgICJyb3QzMF9jdWVkX3RpbHQiLCAicm90MzBfdW5jdWVkIiwNCiAgICAgICJyb3QxNV9jdWVkX3RpbHQiLCAicm90MTVfdW5jdWVkIiwNCiAgICAgICJhX2JhbGxfcm9sbF9hbmltYXRlX3N1cmZhY2UiDQogICAgKQ0KICApKQ0KYGBgDQoNCmBgYHtyLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9Niwgb3V0LndpZHRoPSIxMDAlIn0NCiMgdXNlIGZsaWNrX2RpcmVjdGlvbl94LCB5LCBhbmQgeiB0byBnZXQgbWFnbml0dWRlIG9mIGZsaWNrIGRpcmVjdGlvbg0Kb21uaWJ1c19kZiRtYWduaXR1ZGUgPC0gc3FydChvbW5pYnVzX2RmJGZsaWNrX2RpcmVjdGlvbl94XjIgKyBvbW5pYnVzX2RmJGZsaWNrX2RpcmVjdGlvbl95XjIgKyBvbW5pYnVzX2RmJGZsaWNrX2RpcmVjdGlvbl96XjIpDQpgYGANCg0KIyBTdWNjZXNzIE1hbmlmb2xkcyAtIEFjY2VsZXJhdGVkIEdyb3Vwcw0KDQpGb3IgdGhlc2UgcGxvdHMsIHdlIHdpbGwgdXNlIGRhdGEgb25seSBmcm9tIHRoZSB0cmFpbmluZyBwaGFzZSAodHJhbnNmZXIgdG9vPykuIEJhc2VsaW5lIHBoYXNlcyBhbmQgd2FzaG91dCBwaGFzZXMgYXJlIHRoZSBzYW1lIGZvciBhbGwgZ3JvdXBzLiANCmBgYHtyfQ0KZGF0YV9wZXJfdHJpYWwgPC0gb21uaWJ1c19kZiAlPiUNCiAgZmlsdGVyKA0KICAgIHBoYXNlID09ICJ0cmFpbmluZyIsDQogICAgZXhwZXJpbWVudCAlaW4lIGMoImFjY2VsX3VuY3VlZCIsICJhY2NlbF9jdWVkX3RpbHQiKQ0KICApDQoNCiMgTm90ZSBmb3IgZmlndXJlOiBmYWNldCBieSB0YXJnZXQNCg0KIyBzZXQgdXAgdGhlIHBsb3QNCnAgPC0gZGF0YV9wZXJfdHJpYWwgJT4lDQogIGdncGxvdChhZXMoDQogICAgeCA9IHJhd190aHJvd19kZXZpYXRpb24sDQogICAgeSA9IG1hZ25pdHVkZSwNCiAgICBjb2xvciA9IHJhd19lcnJvcl9zaXplDQogICkpICsNCiAgIyB2ZXJ0aWNhbCBsaW5lIGF0IDANCiAgIyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICIjQ0NDQ0NDIikgKw0KICAjIGNvbG91ciBwYWxldHRlDQogIHNjYWxlX2NvbG91cl9ncmFkaWVudCgNCiAgICBsb3cgPSAiIzdlYWVlMiIsIGhpZ2ggPSAiIzAwMWEzNSIsDQogICAgbGltaXRzID0gYyguMDUsIC43MCksIG5hLnZhbHVlID0gIndoaXRlIiAjIE5vdGU6IG1heCBlcnJvciB2YWx1ZSBpcyB+NjgsIHRhcmdldCByYWRpdXMgaXMgNQ0KICApICsNCiAgIyBhZGQgZGF0YSBwb2ludHMNCiAgZ2VvbV9wb2ludChzaXplID0gMS4zLCBhbHBoYSA9IDAuNywgc3Ryb2tlID0gMCkgKw0KICAjIGZhY2V0DQogIGZhY2V0X3dyYXAofiBmY3RfcmVsZXZlbCh0YXJnZXQsICI5NiIsICI5MiIsICI4OCIsICI4NCIpLCBucm93ID0gMSkgKw0KICAjIHRoZW1lDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIGxhYnMoDQogICAgeCA9IE5VTEwsDQogICAgeSA9ICJUaHJvdyBTcGVlZCAobS9zKSINCiAgKSArDQogIHRoZW1lKA0KICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoDQogICAgICBmaWxsID0gIiMwMDAwMDAiLA0KICAgICAgY29sb3VyID0gIiMwMDAwMDAiDQogICAgKSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dF9zaXplKSwNCiAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCAjIGZhY2V0IGxhYmVscw0KICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKQ0KICApICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMS43LCAyLjIpKSArDQogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC02MCwgMTApKQ0KDQojIHNhdmUNCmlmIChzYXZlX3Bsb3RzKSB7DQogIGdnc2F2ZSgNCiAgICBwLA0KICAgIGZpbGVuYW1lID0gIi4uL2RhdGEvZmlncy9wYXBlcl9maWdzL2ZpZzNfbWFuaWZvbGRzX2FjY2VsLnBkZiIsIGRldmljZSA9ICJwZGYiLA0KICAgIGhlaWdodCA9IDEuNywgd2lkdGggPSA3LjINCiAgKQ0KfQ0KDQojIGdncGxvdGx5KHApDQpwDQpgYGANCg0KYGBge3J9DQpkYXRhX3Blcl90cmlhbCA8LSBvbW5pYnVzX2RmICU+JQ0KICBmaWx0ZXIoDQogICAgcGhhc2UgPT0gInRyYWluaW5nIiwNCiAgICBleHBlcmltZW50ICVpbiUgYygicm90MzBfdW5jdWVkIiwgInJvdDMwX2N1ZWRfdGlsdCIpDQogICkNCg0KIyBOb3RlIGZvciBmaWd1cmU6IGZhY2V0IGJ5IHRhcmdldA0KDQojIHNldCB1cCB0aGUgcGxvdA0KcCA8LSBkYXRhX3Blcl90cmlhbCAlPiUNCiAgZ2dwbG90KGFlcygNCiAgICB4ID0gcmF3X3Rocm93X2RldmlhdGlvbiwNCiAgICB5ID0gbWFnbml0dWRlLA0KICAgIGNvbG9yID0gcmF3X2Vycm9yX3NpemUNCiAgICAjIHNoYXBlID0gcHBpZA0KICApKSArDQogICMgdmVydGljYWwgbGluZSBhdCAwDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IC0zMCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiI0NDQ0NDQyIpICsNCiAgIyBjb2xvdXIgcGFsZXR0ZQ0KICBzY2FsZV9jb2xvdXJfZ3JhZGllbnQoDQogICAgbG93ID0gIiM3ZWFlZTIiLCBoaWdoID0gIiMwMDFhMzUiLA0KICAgIGxpbWl0cyA9IGMoLjA1LCAuNzApLCBuYS52YWx1ZSA9ICJ3aGl0ZSIgIyBOb3RlOiBtYXggZXJyb3IgdmFsdWUgaXMgfjY4LCB0YXJnZXQgcmFkaXVzIGlzIDUNCiAgKSArDQogICMgYWRkIGRhdGEgcG9pbnRzDQogIGdlb21fcG9pbnQoc2l6ZSA9IDEuMywgYWxwaGEgPSAwLjcsIHN0cm9rZSA9IDApICsNCiAgIyBmYWNldA0KICBmYWNldF93cmFwKH4gZmN0X3JlbGV2ZWwodGFyZ2V0LCAiOTYiLCAiOTIiLCAiODgiLCAiODQiKSwgbnJvdyA9IDEpICsNCiAgIyB0aGVtZQ0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICBsYWJzKA0KICAgIHggPSBOVUxMLA0KICAgIHkgPSAiVGhyb3cgU3BlZWQgKG0vcykiDQogICkgKw0KICB0aGVtZSgNCiAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KA0KICAgICAgZmlsbCA9ICIjMDAwMDAwIiwNCiAgICAgIGNvbG91ciA9ICIjMDAwMDAwIg0KICAgICksDQogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRfc2l6ZSksDQogICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgIyBmYWNldCBsYWJlbHMNCiAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkNCiAgKSArDQogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDEuNywgMi4yKSkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtNjAsIDEwKSkNCg0KIyBzYXZlDQppZiAoc2F2ZV9wbG90cykgew0KICBnZ3NhdmUoDQogICAgcCwNCiAgICBmaWxlbmFtZSA9ICIuLi9kYXRhL2ZpZ3MvcGFwZXJfZmlncy9maWczX21hbmlmb2xkc19yb3RhdGVkLnBkZiIsIGRldmljZSA9ICJwZGYiLA0KICAgIGhlaWdodCA9IDEuNywgd2lkdGggPSA3LjINCiAgKQ0KfQ0KDQojIGdncGxvdGx5KHApDQpwDQpgYGANCg0KYGBge3J9DQpkYXRhX3Blcl90cmlhbCA8LSBvbW5pYnVzX2RmICU+JQ0KICBmaWx0ZXIoDQogICAgcGhhc2UgPT0gInRyYWluaW5nIiwNCiAgICBleHBlcmltZW50ICVpbiUgYygiY3VydmVkX2N1ZWRfdGlsdCIsICJjdXJ2ZWRfdW5jdWVkIikNCiAgKQ0KDQojIE5vdGUgZm9yIGZpZ3VyZTogZmFjZXQgYnkgdGFyZ2V0DQoNCiMgc2V0IHVwIHRoZSBwbG90DQpwIDwtIGRhdGFfcGVyX3RyaWFsICU+JQ0KICBnZ3Bsb3QoYWVzKA0KICAgIHggPSByYXdfdGhyb3dfZGV2aWF0aW9uLA0KICAgIHkgPSBtYWduaXR1ZGUsDQogICAgY29sb3IgPSByYXdfZXJyb3Jfc2l6ZQ0KICAgICMgc2hhcGUgPSBwcGlkDQogICkpICsNCiAgIyB2ZXJ0aWNhbCBsaW5lIGF0IDMwDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IC0zMCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiI0NDQ0NDQyIpICsNCiAgIyBjb2xvdXIgcGFsZXR0ZQ0KICBzY2FsZV9jb2xvdXJfZ3JhZGllbnQoDQogICAgbG93ID0gIiM3ZWFlZTIiLCBoaWdoID0gIiMwMDFhMzUiLA0KICAgIGxpbWl0cyA9IGMoLjA1LCAuNzApLCBuYS52YWx1ZSA9ICJ3aGl0ZSIgIyBOb3RlOiBtYXggZXJyb3IgdmFsdWUgaXMgfjY4LCB0YXJnZXQgcmFkaXVzIGlzIDUNCiAgKSArDQogICMgYWRkIGRhdGEgcG9pbnRzDQogIGdlb21fcG9pbnQoc2l6ZSA9IDEuMywgYWxwaGEgPSAwLjcsIHN0cm9rZSA9IDApICsNCiAgIyBmYWNldA0KICBmYWNldF93cmFwKH4gZmN0X3JlbGV2ZWwodGFyZ2V0LCAiOTYiLCAiOTIiLCAiODgiLCAiODQiKSwgbnJvdyA9IDEpICsNCiAgIyB0aGVtZQ0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICBsYWJzKA0KICAgIHggPSBOVUxMLA0KICAgIHkgPSAiVGhyb3cgU3BlZWQgKG0vcykiDQogICkgKw0KICB0aGVtZSgNCiAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KA0KICAgICAgZmlsbCA9ICIjMDAwMDAwIiwNCiAgICAgIGNvbG91ciA9ICIjMDAwMDAwIg0KICAgICksDQogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRfc2l6ZSksDQogICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgIyBmYWNldCBsYWJlbHMNCiAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkNCiAgKSArDQogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDEuNywgMi4yKSkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtNjAsIDEwKSkNCg0KIyBzYXZlDQppZiAoc2F2ZV9wbG90cykgew0KICBnZ3NhdmUoDQogICAgcCwNCiAgICBmaWxlbmFtZSA9ICIuLi9kYXRhL2ZpZ3MvcGFwZXJfZmlncy9maWczX21hbmlmb2xkc19jdXJ2ZWQucGRmIiwgZGV2aWNlID0gInBkZiIsDQogICAgaGVpZ2h0ID0gMS43LCB3aWR0aCA9IDcuMg0KICApDQp9DQoNCiMgZ2dwbG90bHkocCkNCnANCmBgYA0KDQoNCmBgYHtyfQ0KbnVtX2V4cHMgPC0gNA0KYGBgDQoNCiMjIE5vcm1hbGl6ZWQgVHJhaW5pbmcgUGhhc2VzDQpgYGB7ciwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTYsIG91dC53aWR0aD0iMTAwJSJ9DQojIHJlc3Qgb2YgdGhlIGV4cHMNCmRhdGFfcGVyX2dyb3VwIDwtIG9tbmlidXNfZGYgJT4lDQogIGZpbHRlcigNCiAgICBleHBlcmltZW50ICVpbiUgYygNCiAgICAgICJyb3QzMF9jdWVkX3RpbHQiLCAicm90MzBfdW5jdWVkIiwNCiAgICAgICJjdXJ2ZWRfY3VlZF90aWx0IiwgImN1cnZlZF91bmN1ZWQiDQogICAgKSwNCiAgICB0cmlhbF9udW0gPj0gMjE0LA0KICAgIHBoYXNlID09ICJ0cmFpbmluZyIsDQogICAgbGVhcm5pbmdfYW5kX2RlY2F5X2N1cnZlcyA9PSAxDQogICkgJT4lDQogIGdyb3VwX2J5KGV4cGVyaW1lbnQsIHBoYXNlLCB0ZXN0X3R5cGUsIHRyaWFsX251bSkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBtZWFuX2RldmlhdGlvbiA9IG1lYW4obm9ybV90aHJvd19kZXZpYXRpb24pLA0KICAgIGNpX2RldmlhdGlvbiA9IHZlY3Rvcl9jb25maW50KG5vcm1fdGhyb3dfZGV2aWF0aW9uKSwNCiAgICAuZ3JvdXBzID0gImRyb3AiDQogICkgJT4lDQogIGFycmFuZ2UoZXhwZXJpbWVudCwgdHJpYWxfbnVtKQ0KDQojIGFkZCBhIGR1bW15IGNvbHVtbiB3aXRoIHJlcGVhdGluZyBzZXF1ZW5jZQ0KIyBOT1RFOiB0aGlzIGNhbid0IGJlIGNvbWJpbmVkIHdpdGggYWJvdmUgc2luY2Ugd2UgYXJlIHVzaW5nIG5yb3cNCmRhdGFfcGVyX2dyb3VwIDwtIGRhdGFfcGVyX2dyb3VwICU+JQ0KICBtdXRhdGUoZHVtbXlfeCA9IHJlcCgxOihucm93KGRhdGFfcGVyX2dyb3VwKSAvIG51bV9leHBzKSwNCiAgICBsZW5ndGgub3V0ID0gbnJvdyhkYXRhX3Blcl9ncm91cCkNCiAgKSkNCg0KIyBzZXQgdXAgcGxvdA0KcCA8LSBkYXRhX3Blcl9ncm91cCAlPiUNCiAgZ2dwbG90KA0KICAgIGFlcygNCiAgICAgIHggPSBkdW1teV94LCB5ID0gbWVhbl9kZXZpYXRpb24sIGNvbG91ciA9IGV4cGVyaW1lbnQNCiAgICApDQogICkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICB0aGVtZSgNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dF9zaXplKQ0KICApICsNCiAgbGFicygNCiAgICB4ID0gIlRyaWFsIiwNCiAgICB5ID0gIk5vcm1hbGl6ZWQgVGhyb3cgQW5nbGUiDQogICkgKw0KICAjIGFkZCBob3Jpem9udGFsIGxpbmVzDQogIGdlb21faGxpbmUoDQogICAgeWludGVyY2VwdCA9IGMoMCwgMSksIGxpbmV3aWR0aCA9IDAuNCwNCiAgICBjb2xvdXIgPSAiI0NDQ0NDQyIsIGxpbmV0eXBlID0gInNvbGlkIg0KICApICsNCiAgZ2VvbV9obGluZSgNCiAgICB5aW50ZXJjZXB0ID0gYygwLjUsIDEuNSksIGxpbmV3aWR0aCA9IDAuNCwNCiAgICBjb2xvdXIgPSAiI0NDQ0NDQyIsIGxpbmV0eXBlID0gImRhc2hlZCINCiAgKSArDQogICMgc2V0IGNvbG91ciBwYWxldHRlDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gcGFsbGV0ZV9saXN0KSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHBhbGxldGVfbGlzdCkgKyAjIHNjYWxlIGF4ZXMNCiAgc2NhbGVfeV9jb250aW51b3VzKA0KICAgIGJyZWFrcyA9IGMoMCwgMC41LCAxLCAxLjUpLA0KICAgIGxhYmVscyA9IGMoMCwgMC41LCAxLCAxLjUpLA0KICAgIGxpbWl0cyA9IGMoLTAuMiwgMS41KQ0KICApICsNCiAgc2NhbGVfeF9jb250aW51b3VzKA0KICAgIGJyZWFrcyA9IGN1cnZlX3hfYnJlYWtzLA0KICAgIGxhYmVscyA9IGN1cnZlX3hfYnJlYWtzDQogICkNCg0KIyBhZGQgY29uZmlkZW5jZSBpbnRlcnZhbHMgYW5kIGRhdGEgcG9pbnRzDQpmb3IgKHVuaXFfcGhhc2UgaW4gdW5pcXVlKGRhdGFfcGVyX2dyb3VwJHBoYXNlKSkgew0KICAjIGdldCB0aGUgZGF0YSBmb3IgdGhpcyBibG9jaw0KICB0b19wbG90X2RhdGEgPC0gZmlsdGVyKGRhdGFfcGVyX2dyb3VwLCBwaGFzZSA9PSB1bmlxX3BoYXNlKQ0KDQogIHAgPC0gcCArIGdlb21fcmliYm9uKA0KICAgIGRhdGEgPSB0b19wbG90X2RhdGEsDQogICAgYWVzKA0KICAgICAgeW1pbiA9IG1lYW5fZGV2aWF0aW9uIC0gY2lfZGV2aWF0aW9uLA0KICAgICAgeW1heCA9IG1lYW5fZGV2aWF0aW9uICsgY2lfZGV2aWF0aW9uLA0KICAgICAgZmlsbCA9IGV4cGVyaW1lbnQNCiAgICApLCBjb2xvdXIgPSBOQSwgYWxwaGEgPSAwLjMNCiAgKSArIGdlb21fbGluZSgNCiAgICBkYXRhID0gdG9fcGxvdF9kYXRhDQogICkNCn0NCg0KIyBzYXZlDQppZiAoc2F2ZV9wbG90cykgew0KICBnZ3NhdmUoDQogICAgcCwNCiAgICBmaWxlbmFtZSA9ICIuLi9kYXRhL2ZpZ3MvcGFwZXJfZmlncy9maWczX2V4cHNfbm9ybWFsaXplZF90cmFpbmluZy5wZGYiLCBkZXZpY2UgPSAicGRmIiwNCiAgICBoZWlnaHQgPSAyLCB3aWR0aCA9IGN1cnZlX2ZpZ193aWR0aA0KICApDQp9DQoNCnANCmBgYA0KDQpgYGB7cn0NCmZpdHRlZF9kYXRhIDwtIGZpdHRlZF9sZWFybmluZ19yYXRlX2RmICU+JQ0KICBmaWx0ZXIoDQogICAgZXhwZXJpbWVudCAlaW4lIGMoDQogICAgICAicm90MzBfY3VlZF90aWx0IiwgInJvdDMwX3VuY3VlZCIsDQogICAgICAiY3VydmVkX2N1ZWRfdGlsdCIsICJjdXJ2ZWRfdW5jdWVkIg0KICAgICksDQogICAgcGhhc2UgPT0gInRyYWluaW5nIg0KICApICU+JQ0KICBtdXRhdGUoDQogICAgcGVydCA9IGZhY3RvcihzdHJfc3BsaXRfZml4ZWQoZXhwZXJpbWVudCwgIl8iLCAyKVssIDFdKSwNCiAgICBjdWUgPSBmYWN0b3Ioc3RyX3NwbGl0X2ZpeGVkKGV4cGVyaW1lbnQsICJfIiwgMilbLCAyXSkNCiAgKQ0KDQpwIDwtIGZpdHRlZF9kYXRhICU+JQ0KICBnZ3Bsb3QoDQogICAgYWVzKHggPSB4ICsgMSwgeSA9IHksIGNvbG91ciA9IGV4cGVyaW1lbnQpDQogICkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICB0aGVtZSgNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dF9zaXplKQ0KICApICsNCiAgbGFicygNCiAgICB4ID0gIlRyaWFsIiwNCiAgICB5ID0gIk5vcm1hbGl6ZWQgVGhyb3cgQW5nbGUiDQogICkgKw0KICAjIGFkZCBob3Jpem9udGFsIGxpbmVzDQogIGdlb21faGxpbmUoDQogICAgeWludGVyY2VwdCA9IGMoMCwgMSksIGxpbmV3aWR0aCA9IDAuNCwNCiAgICBjb2xvdXIgPSAiI0NDQ0NDQyIsIGxpbmV0eXBlID0gInNvbGlkIg0KICApICsNCiAgZ2VvbV9obGluZSgNCiAgICB5aW50ZXJjZXB0ID0gYygwLjUsIDEuNSksIGxpbmV3aWR0aCA9IDAuNCwNCiAgICBjb2xvdXIgPSAiI0NDQ0NDQyIsIGxpbmV0eXBlID0gImRhc2hlZCINCiAgKSArDQogICMgc2V0IGNvbG91ciBwYWxldHRlDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gcGFsbGV0ZV9saXN0KSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHBhbGxldGVfbGlzdCkgKyAjIHNjYWxlIGF4ZXMNCiAgc2NhbGVfeV9jb250aW51b3VzKA0KICAgIGJyZWFrcyA9IGMoMCwgMC41LCAxLCAxLjUpLA0KICAgIGxhYmVscyA9IGMoMCwgMC41LCAxLCAxLjUpLA0KICAgIGxpbWl0cyA9IGMoLTAuMiwgMS41KQ0KICApICsNCiAgc2NhbGVfeF9jb250aW51b3VzKA0KICAgIGJyZWFrcyA9IGN1cnZlX3hfYnJlYWtzLA0KICAgIGxhYmVscyA9IGN1cnZlX3hfYnJlYWtzDQogICkgKw0KICBnZW9tX2xpbmUoKQ0KDQojIHNhdmUNCmlmIChzYXZlX3Bsb3RzKSB7DQogIGdnc2F2ZSgNCiAgICBwLA0KICAgIGZpbGVuYW1lID0gIi4uL2RhdGEvZmlncy9wYXBlcl9maWdzL2ZpZzNfY3VydmVkX3RyYWluaW5nX2ZpdHRlZF9vbmx5LnBkZiIsIGRldmljZSA9ICJwZGYiLA0KICAgIGhlaWdodCA9IDIsIHdpZHRoID0gY3VydmVfZmlnX3dpZHRoDQogICkNCn0NCg0KcA0KYGBgDQoNCiMjIFRyYWluaW5nIC0gRml0IExlYXJuaW5nIFJhdGVzDQpgYGB7ciwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTYsIG91dC53aWR0aD0iMTAwJSJ9DQpkYXRhX3Blcl9wcHQgPC0gaW5pdF9sZWFybmluZ19yYXRlcyAlPiUNCiAgZmlsdGVyKA0KICAgIGV4cGVyaW1lbnQgJWluJSBjKA0KICAgICAgInJvdDMwX2N1ZWRfdGlsdCIsICJyb3QzMF91bmN1ZWQiLA0KICAgICAgImN1cnZlZF9jdWVkX3RpbHQiLCAiY3VydmVkX3VuY3VlZCINCiAgICApLA0KICAgIHBoYXNlID09ICJ0cmFpbmluZyINCiAgKSAlPiUNCiAgbXV0YXRlKA0KICAgIHBlcnQgPSBmYWN0b3Ioc3RyX3NwbGl0X2ZpeGVkKGV4cGVyaW1lbnQsICJfIiwgMilbLCAxXSksDQogICAgY3VlID0gZmFjdG9yKHN0cl9zcGxpdF9maXhlZChleHBlcmltZW50LCAiXyIsIDIpWywgMl0pLA0KICAgIHBwaWQgPSBmYWN0b3IocHBpZCkNCiAgKQ0KDQpkYXRhX3Blcl9ncm91cCA8LSBkYXRhX3Blcl9wcHQgJT4lDQogIGdyb3VwX2J5KGV4cGVyaW1lbnQsIHBoYXNlKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIG1lYW5fbGVhcm5pbmdfcmF0ZSA9IG1lYW4oZXhwX2ZpdF9sYW1iZGEpLA0KICAgIGNpX2xlYXJuaW5nX3JhdGUgPSB2ZWN0b3JfY29uZmludChleHBfZml0X2xhbWJkYSksDQogICAgbWVhbl9oaWdoID0gbWVhbihleHBfZml0X04wKSwNCiAgICBjaV9oaWdoID0gdmVjdG9yX2NvbmZpbnQoZXhwX2ZpdF9OMCksDQogICAgbiA9IG4oKSwNCiAgICAuZ3JvdXBzID0gImRyb3AiDQogICkNCg0KcCA8LSBkYXRhX3Blcl9ncm91cCAlPiUNCiAgZ2dwbG90KA0KICAgIGFlcyh4ID0gZXhwZXJpbWVudCwgeSA9IG1lYW5fbGVhcm5pbmdfcmF0ZSwgY29sb3VyID0gZXhwZXJpbWVudCkNCiAgKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIGxhYnMoDQogICAgeCA9IHBlcl9ncm91cF94X2xhYnMsDQogICAgeSA9ICJMZWFybmluZyBSYXRlIg0KICApICsNCiAgIyByZW1vdmUgYWxsIHggYXhpcyBsYWJlbHMNCiAgdGhlbWUoDQogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRfc2l6ZSkNCiAgKSArDQogICMgY29sb3VyIGxlZ2VuZCBzZXR0aW5ncw0KICBndWlkZXMoDQogICAgY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkNCiAgKSArDQogICMgc2V0IGNvbG91ciBwYWxldHRlDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gcGFsbGV0ZV9saXN0KSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKA0KICAgIHZhbHVlcyA9IHBhbGxldGVfbGlzdA0KICApICsNCiAgIyBhZGQgaG9yaXpvbnRhbCBsaW5lcw0KICBnZW9tX2hsaW5lKA0KICAgIHlpbnRlcmNlcHQgPSBjKDAsIDEpLCBsaW5ld2lkdGggPSAwLjQsDQogICAgY29sb3VyID0gIiNDQ0NDQ0MiLCBsaW5ldHlwZSA9ICJzb2xpZCINCiAgKSArDQogIGdlb21faGxpbmUoDQogICAgeWludGVyY2VwdCA9IGMoMC4yNSwgMC41LCAwLjc1KSwgbGluZXdpZHRoID0gMC40LA0KICAgIGNvbG91ciA9ICIjQ0NDQ0NDIiwgbGluZXR5cGUgPSAiZGFzaGVkIg0KICApICsNCiAgIyB5LWF4aXMgc2NhbGUNCiAgc2NhbGVfeV9jb250aW51b3VzKA0KICAgICMgbGltaXRzID0gYygtMzUsIDUpLA0KICAgIGJyZWFrcyA9IGMoMCwgMC4yNSwgMC41LCAwLjc1LCAxKSwNCiAgICBsYWJlbHMgPSBjKDAsIDAuMjUsIDAuNSwgMC43NSwgMSkNCiAgKSArDQogIHNjYWxlX3hfZGlzY3JldGUoDQogICAgbGFiZWxzID0gYygwLCAwLCAwLCAwKQ0KICApICsNCiAgIyBhZGQgZGF0YSBwb2ludHMNCiAgZ2VvbV9iZWVzd2FybSgNCiAgICBkYXRhID0gZGF0YV9wZXJfcHB0LA0KICAgIGFlcygNCiAgICAgIHkgPSBleHBfZml0X2xhbWJkYQ0KICAgICksDQogICAgYWxwaGEgPSAwLjEsDQogICAgc2l6ZSA9IDENCiAgKSArDQogIGdlb21fbGluZXJhbmdlKGFlcygNCiAgICB5bWluID0gbWVhbl9sZWFybmluZ19yYXRlIC0gY2lfbGVhcm5pbmdfcmF0ZSwNCiAgICB5bWF4ID0gbWVhbl9sZWFybmluZ19yYXRlICsgY2lfbGVhcm5pbmdfcmF0ZQ0KICApLCBhbHBoYSA9IDAuNSwgbHdkID0gMikgKw0KICBnZW9tX3BvaW50KCkNCg0KIyBzYXZlDQppZiAoc2F2ZV9wbG90cykgew0KICBnZ3NhdmUoDQogICAgcCwNCiAgICBmaWxlbmFtZSA9ICIuLi9kYXRhL2ZpZ3MvcGFwZXJfZmlncy9maWczX3RyYWluaW5nX2xlYXJuaW5nX3JhdGVzLnBkZiIsIGRldmljZSA9ICJwZGYiLA0KICAgIGhlaWdodCA9IDIsIHdpZHRoID0gcGVyX2dyb3VwX2ZpZ193aWR0aA0KICApDQp9DQoNCnANCmBgYA0KDQojIyMgQU5PVkEgLSAzIGxldmVscw0KYGBge3J9DQoodGVtcF9BTk9WQSA8LSBhb3ZfY2FyKA0KICBleHBfZml0X2xhbWJkYSB+IHBlcnQgKiBjdWUgKyBFcnJvcihwcGlkKSwNCiAgZGF0YV9wZXJfcHB0LA0KICBpbmNsdWRlX2FvdiA9IFRSVUUNCikpDQoNCnByaW50KCJCYXllcyBhbm92YXMgYW5kIGJheWVzIGZhY3RvcnM6IikNCnByaW50KCIiKQ0KDQpiZiA8LSBhbm92YUJGKGV4cF9maXRfbGFtYmRhIH4gcGVydCAqIGN1ZSwgZGF0YSA9IGRhdGEuZnJhbWUoZGF0YV9wZXJfcHB0KSwgcHJvZ3Jlc3MgPSBGQUxTRSkNCnByaW50KGJmKQ0KcHJpbnQoYmF5ZXNmYWN0b3JfaW5jbHVzaW9uKGJmKSkNCmBgYA0KYGBge3J9DQojIE5vdGU6IGRlZmF1bHQgbXVsdGlwbGljaXR5IGNvcnJlY3Rpb24gZm9yIHBhaXJzIHN1bW1hcnkgaXMgVHVrZXkgSFNEDQpwcmludCgiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRU1NcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpDQplbW1zX29iaiA8LSBlbW1lYW5zKHRlbXBfQU5PVkEsICJwZXJ0IikNCnByaW50KHB3cG0oZW1tc19vYmosIGRpZmZzID0gRkFMU0UpKQ0KDQpwcmludCgiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRU1NcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpDQplbW1zX29iaiA8LSBlbW1lYW5zKHRlbXBfQU5PVkEsICJjdWUiKQ0KcHJpbnQocHdwbShlbW1zX29iaiwgZGlmZnMgPSBGQUxTRSkpDQoNCiMgRWZmZWN0IHNpemUgaXMgQ29oZW4ncyBEDQplZmZfc2l6ZShlbW1zX29iaiwgZWRmID0gdGVtcF9BTk9WQSRhbm92YV90YWJsZSRgZGVuIERmYFsxXSwgc2lnbWEgPSBzaWdtYSh0ZW1wX0FOT1ZBJGxtKSkNCg0KcHJpbnQoIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZ1bGwgVHVrZXkgSFNEIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIikNCnByaW50KFR1a2V5SFNEKHRlbXBfQU5PVkEkYW92KSkNCg0KcHJpbnQoZWZmX3NpemUoZW1tZWFucyh0ZW1wX0FOT1ZBJGFvdiwgYygicGVydCIsICJjdWUiKSksDQogIGVkZiA9IHRlbXBfQU5PVkEkYW5vdmFfdGFibGUkYGRlbiBEZmBbMV0sDQogIHNpZ21hID0gc2lnbWEodGVtcF9BTk9WQSRsbSkNCikpDQpgYGANCg0KIyMgVHJhaW5pbmcgLSBGaXQgSGlnaCBQb2ludHMgKEFzeW1wdG90ZXMpDQpgYGB7ciwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTYsIG91dC53aWR0aD0iMTAwJSJ9DQpwIDwtIGRhdGFfcGVyX2dyb3VwICU+JQ0KICBnZ3Bsb3QoDQogICAgYWVzKHggPSBleHBlcmltZW50LCB5ID0gbWVhbl9oaWdoLCBjb2xvdXIgPSBleHBlcmltZW50KQ0KICApICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgbGFicygNCiAgICB4ID0gcGVyX2dyb3VwX3hfbGFicywNCiAgICB5ID0gIkFzeW1wdG90ZSBvZiBBZGFwdGF0aW9uIg0KICApICsNCiAgIyBmb3IgdGhlIGNvbG91ciBsZWdlbmQsIG9ubHkgc2hvdyB0aGUgZmlyc3QgNw0KICAjIE5vdGUgdGhpcyBkb2Vzbid0IHdvcmsgZm9yIHRoZSBwbG90bHkgcGxvdA0KICBndWlkZXMoDQogICAgY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkNCiAgKSArDQogICMgc2V0IGNvbG91ciBwYWxldHRlDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gcGFsbGV0ZV9saXN0KSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHBhbGxldGVfbGlzdCkgKw0KICAjIGFkZCBob3Jpem9udGFsIGxpbmVzDQogIGdlb21faGxpbmUoDQogICAgeWludGVyY2VwdCA9IGMoMSksIGxpbmV3aWR0aCA9IDAuNCwNCiAgICBjb2xvdXIgPSAiI0NDQ0NDQyIsIGxpbmV0eXBlID0gInNvbGlkIg0KICApICsNCiAgZ2VvbV9obGluZSgNCiAgICB5aW50ZXJjZXB0ID0gYygwLjUsIDEuNSksIGxpbmV3aWR0aCA9IDAuNCwNCiAgICBjb2xvdXIgPSAiI0NDQ0NDQyIsIGxpbmV0eXBlID0gImRhc2hlZCINCiAgKSArDQogICMgeS1heGlzIHNjYWxlDQogIHNjYWxlX3lfY29udGludW91cygNCiAgICBsaW1pdHMgPSBjKDAuNSwgMS43NSksDQogICAgYnJlYWtzID0gYygwLjUsIDAuNzUsIDEsIDEuMjUsIDEuNSksDQogICAgbGFiZWxzID0gYygwLjUsIDAuNzUsIDEsIDEuMjUsIDEuNSkNCiAgKSArDQogIHNjYWxlX3hfZGlzY3JldGUoDQogICAgbGFiZWxzID0gYygwLCAwLCAwLCAwKQ0KICApICsNCiAgIyByZW1vdmUgYWxsIHggYXhpcyBsYWJlbHMNCiAgdGhlbWUoDQogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRfc2l6ZSkNCiAgKSArDQogICMgYWRkIGRhdGEgcG9pbnRzDQogIGdlb21fYmVlc3dhcm0oDQogICAgZGF0YSA9IGRhdGFfcGVyX3BwdCwNCiAgICBhZXMoDQogICAgICB5ID0gZXhwX2ZpdF9OMA0KICAgICksDQogICAgYWxwaGEgPSAwLjEsDQogICAgc2l6ZSA9IDENCiAgKSArDQogIGdlb21fbGluZXJhbmdlKGFlcygNCiAgICB5bWluID0gbWVhbl9oaWdoIC0gY2lfaGlnaCwNCiAgICB5bWF4ID0gbWVhbl9oaWdoICsgY2lfaGlnaA0KICApLCBhbHBoYSA9IDAuNSwgbHdkID0gMikgKw0KICBnZW9tX3BvaW50KCkNCg0KIyBzYXZlDQppZiAoc2F2ZV9wbG90cykgew0KICBnZ3NhdmUoDQogICAgcCwNCiAgICBmaWxlbmFtZSA9ICIuLi9kYXRhL2ZpZ3MvcGFwZXJfZmlncy9maWczX3RyYWluaW5nX2FzeW1wdG90ZXMucGRmIiwgZGV2aWNlID0gInBkZiIsDQogICAgaGVpZ2h0ID0gMiwgd2lkdGggPSBwZXJfZ3JvdXBfZmlnX3dpZHRoDQogICkNCn0NCg0KcA0KYGBgDQojIyMgQU5PVkEgLSAzIGxldmVscw0KYGBge3J9DQoodGVtcF9BTk9WQSA8LSBhb3ZfY2FyKA0KICBleHBfZml0X04wIH4gcGVydCAqIGN1ZSArIEVycm9yKHBwaWQpLA0KICBkYXRhX3Blcl9wcHQsDQogIGluY2x1ZGVfYW92ID0gVFJVRQ0KKSkNCg0KcHJpbnQoIkJheWVzIGFub3ZhcyBhbmQgYmF5ZXMgZmFjdG9yczoiKQ0KcHJpbnQoIiIpDQoNCmJmIDwtIGFub3ZhQkYoZXhwX2ZpdF9OMCB+IHBlcnQgKiBjdWUsIGRhdGEgPSBkYXRhLmZyYW1lKGRhdGFfcGVyX3BwdCksIHByb2dyZXNzID0gRkFMU0UpDQpwcmludChiZikNCnByaW50KGJheWVzZmFjdG9yX2luY2x1c2lvbihiZikpDQpgYGANCmBgYHtyfQ0KIyBOb3RlOiBkZWZhdWx0IG11bHRpcGxpY2l0eSBjb3JyZWN0aW9uIGZvciBwYWlycyBzdW1tYXJ5IGlzIFR1a2V5IEhTRA0KcHJpbnQoIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEVNTXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iKQ0KZW1tc19vYmogPC0gZW1tZWFucyh0ZW1wX0FOT1ZBLCAicGVydCIpDQpwcmludChwd3BtKGVtbXNfb2JqLCBkaWZmcyA9IEZBTFNFKSkNCg0KIyBFZmZlY3Qgc2l6ZSBpcyBDb2hlbidzIEQNCmVmZl9zaXplKGVtbXNfb2JqLCBlZGYgPSB0ZW1wX0FOT1ZBJGFub3ZhX3RhYmxlJGBkZW4gRGZgWzFdLCBzaWdtYSA9IHNpZ21hKHRlbXBfQU5PVkEkbG0pKQ0KDQpwcmludCgiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRnVsbCBUdWtleSBIU0QgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iKQ0KcHJpbnQoVHVrZXlIU0QodGVtcF9BTk9WQSRhb3YpKQ0KDQpwcmludChlZmZfc2l6ZShlbW1lYW5zKHRlbXBfQU5PVkEkYW92LCBjKCJwZXJ0IiwgImN1ZSIpKSwNCiAgZWRmID0gdGVtcF9BTk9WQSRhbm92YV90YWJsZSRgZGVuIERmYFsxXSwNCiAgc2lnbWEgPSBzaWdtYSh0ZW1wX0FOT1ZBJGxtKQ0KKSkNCmBgYA0KDQojIyBOb3JtYWxpemVkIFdhc2hvdXQgUGhhc2VzDQpgYGB7ciwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTYsIG91dC53aWR0aD0iMTAwJSJ9DQojIHJlc3Qgb2YgdGhlIGV4cHMNCmRhdGFfcGVyX2dyb3VwIDwtIG9tbmlidXNfZGYgJT4lDQogIGZpbHRlcigNCiAgICBleHBlcmltZW50ICVpbiUgYygNCiAgICAgICJyb3QzMF9jdWVkX3RpbHQiLCAicm90MzBfdW5jdWVkIiwNCiAgICAgICJjdXJ2ZWRfY3VlZF90aWx0IiwgImN1cnZlZF91bmN1ZWQiDQogICAgKSwNCiAgICB0cmlhbF9udW0gPj0gMjE0LA0KICAgIHBoYXNlID09ICJ3YXNob3V0IiwNCiAgICBsZWFybmluZ19hbmRfZGVjYXlfY3VydmVzID09IDENCiAgKSAlPiUNCiAgZ3JvdXBfYnkoZXhwZXJpbWVudCwgcGhhc2UsIHRyaWFsX251bSkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBtZWFuX2RldmlhdGlvbiA9IG1lYW4obm9ybV90aHJvd19kZXZpYXRpb24pLA0KICAgIGNpX2RldmlhdGlvbiA9IHZlY3Rvcl9jb25maW50KG5vcm1fdGhyb3dfZGV2aWF0aW9uKSwNCiAgICAuZ3JvdXBzID0gImRyb3AiDQogICkgJT4lDQogIGFycmFuZ2UoZXhwZXJpbWVudCwgdHJpYWxfbnVtKQ0KDQojIGFkZCBhIGR1bW15IGNvbHVtbiB3aXRoIHJlcGVhdGluZyBzZXF1ZW5jZQ0KIyBOT1RFOiB0aGlzIGNhbid0IGJlIGNvbWJpbmVkIHdpdGggYWJvdmUgc2luY2Ugd2UgYXJlIHVzaW5nIG5yb3cNCmRhdGFfcGVyX2dyb3VwIDwtIGRhdGFfcGVyX2dyb3VwICU+JQ0KICBtdXRhdGUoZHVtbXlfeCA9IHJlcCgxOihucm93KGRhdGFfcGVyX2dyb3VwKSAvIG51bV9leHBzKSwNCiAgICBsZW5ndGgub3V0ID0gbnJvdyhkYXRhX3Blcl9ncm91cCkNCiAgKSkNCg0KIyBzZXQgdXAgcGxvdA0KcCA8LSBkYXRhX3Blcl9ncm91cCAlPiUNCiAgZ2dwbG90KA0KICAgIGFlcygNCiAgICAgIHggPSBkdW1teV94LCB5ID0gbWVhbl9kZXZpYXRpb24sIGNvbG91ciA9IGV4cGVyaW1lbnQNCiAgICApDQogICkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICB0aGVtZSgNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dF9zaXplKQ0KICApICsNCiAgbGFicygNCiAgICB4ID0gIlRyaWFsIiwNCiAgICB5ID0gIk5vcm1hbGl6ZWQgVGhyb3cgQW5nbGUiDQogICkgKw0KICAjIGFkZCBob3Jpem9udGFsIGxpbmVzDQogIGdlb21faGxpbmUoDQogICAgeWludGVyY2VwdCA9IGMoMCwgMSksIGxpbmV3aWR0aCA9IDAuNCwNCiAgICBjb2xvdXIgPSAiI0NDQ0NDQyIsIGxpbmV0eXBlID0gInNvbGlkIg0KICApICsNCiAgZ2VvbV9obGluZSgNCiAgICB5aW50ZXJjZXB0ID0gYygwLjUsIDEuNSksIGxpbmV3aWR0aCA9IDAuNCwNCiAgICBjb2xvdXIgPSAiI0NDQ0NDQyIsIGxpbmV0eXBlID0gImRhc2hlZCINCiAgKSArDQogICMgc2V0IGNvbG91ciBwYWxldHRlDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gcGFsbGV0ZV9saXN0KSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHBhbGxldGVfbGlzdCkgKyAjIHNjYWxlIGF4ZXMNCiAgc2NhbGVfeV9jb250aW51b3VzKA0KICAgIGJyZWFrcyA9IGMoMCwgMC41LCAxLCAxLjUpLA0KICAgIGxhYmVscyA9IGMoMCwgMC41LCAxLCAxLjUpDQogICkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoDQogICAgYnJlYWtzID0gY3VydmVfeF9icmVha3MsDQogICAgbGFiZWxzID0gY3VydmVfeF9icmVha3MNCiAgKQ0KDQojIGFkZCBjb25maWRlbmNlIGludGVydmFscyBhbmQgZGF0YSBwb2ludHMNCmZvciAodW5pcV9waGFzZSBpbiB1bmlxdWUoZGF0YV9wZXJfZ3JvdXAkcGhhc2UpKSB7DQogICMgZ2V0IHRoZSBkYXRhIGZvciB0aGlzIGJsb2NrDQogIHRvX3Bsb3RfZGF0YSA8LSBmaWx0ZXIoZGF0YV9wZXJfZ3JvdXAsIHBoYXNlID09IHVuaXFfcGhhc2UpDQoNCiAgcCA8LSBwICsgZ2VvbV9yaWJib24oDQogICAgZGF0YSA9IHRvX3Bsb3RfZGF0YSwNCiAgICBhZXMoDQogICAgICB5bWluID0gbWVhbl9kZXZpYXRpb24gLSBjaV9kZXZpYXRpb24sDQogICAgICB5bWF4ID0gbWVhbl9kZXZpYXRpb24gKyBjaV9kZXZpYXRpb24sDQogICAgICBmaWxsID0gZXhwZXJpbWVudA0KICAgICksIGNvbG91ciA9IE5BLCBhbHBoYSA9IDAuMw0KICApICsgZ2VvbV9saW5lKA0KICAgIGRhdGEgPSB0b19wbG90X2RhdGENCiAgKQ0KfQ0KDQojIHNhdmUNCmlmIChzYXZlX3Bsb3RzKSB7DQogIGdnc2F2ZSgNCiAgICBwLA0KICAgIGZpbGVuYW1lID0gIi4uL2RhdGEvZmlncy9wYXBlcl9maWdzL2ZpZzNfbm9ybWFsaXplZF93YXNob3V0LnBkZiIsIGRldmljZSA9ICJwZGYiLA0KICAgIGhlaWdodCA9IDIsIHdpZHRoID0gMi41DQogICkNCn0NCg0KcA0KYGBgDQojIyBXYXNob3V0IC0gRml0IExlYXJuaW5nIFJhdGVzDQpgYGB7ciwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTYsIG91dC53aWR0aD0iMTAwJSJ9DQpkYXRhX3Blcl9wcHQgPC0gaW5pdF9sZWFybmluZ19yYXRlcyAlPiUNCiAgZmlsdGVyKA0KICAgIGV4cGVyaW1lbnQgJWluJSBjKA0KICAgICAgInJvdDMwX2N1ZWRfdGlsdCIsICJyb3QzMF91bmN1ZWQiLA0KICAgICAgImN1cnZlZF9jdWVkX3RpbHQiLCAiY3VydmVkX3VuY3VlZCINCiAgICApLA0KICAgIHBoYXNlID09ICJ3YXNob3V0Ig0KICApICU+JQ0KICBtdXRhdGUoDQogICAgcGVydCA9IGZhY3RvcihzdHJfc3BsaXRfZml4ZWQoZXhwZXJpbWVudCwgIl8iLCAyKVssIDFdKSwNCiAgICBjdWUgPSBmYWN0b3Ioc3RyX3NwbGl0X2ZpeGVkKGV4cGVyaW1lbnQsICJfIiwgMilbLCAyXSksDQogICAgcHBpZCA9IGZhY3RvcihwcGlkKQ0KICApDQoNCmRhdGFfcGVyX2dyb3VwIDwtIGRhdGFfcGVyX3BwdCAlPiUNCiAgZ3JvdXBfYnkoZXhwZXJpbWVudCwgcGhhc2UpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgbWVhbl9sZWFybmluZ19yYXRlID0gbWVhbihleHBfZml0X2xhbWJkYSksDQogICAgY2lfbGVhcm5pbmdfcmF0ZSA9IHZlY3Rvcl9jb25maW50KGV4cF9maXRfbGFtYmRhKSwNCiAgICBtZWFuX2hpZ2ggPSBtZWFuKGV4cF9maXRfTjApLA0KICAgIGNpX2hpZ2ggPSB2ZWN0b3JfY29uZmludChleHBfZml0X04wKSwNCiAgICAuZ3JvdXBzID0gImRyb3AiDQogICkNCg0KcCA8LSBkYXRhX3Blcl9ncm91cCAlPiUNCiAgZ2dwbG90KA0KICAgIGFlcyh4ID0gZXhwZXJpbWVudCwgeSA9IG1lYW5fbGVhcm5pbmdfcmF0ZSwgY29sb3VyID0gZXhwZXJpbWVudCkNCiAgKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIGxhYnMoDQogICAgeCA9IHBlcl9ncm91cF94X2xhYnMsDQogICAgeSA9ICJEZWNheSBSYXRlIg0KICApICsNCiAgIyByZW1vdmUgYWxsIHggYXhpcyBsYWJlbHMNCiAgdGhlbWUoDQogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRfc2l6ZSkNCiAgKSArDQogICMgY29sb3VyIGxlZ2VuZCBzZXR0aW5ncw0KICBndWlkZXMoDQogICAgY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkNCiAgKSArDQogICMgc2V0IGNvbG91ciBwYWxldHRlDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gcGFsbGV0ZV9saXN0KSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKA0KICAgIHZhbHVlcyA9IHBhbGxldGVfbGlzdA0KICApICsNCiAgIyBhZGQgaG9yaXpvbnRhbCBsaW5lcw0KICBnZW9tX2hsaW5lKA0KICAgIHlpbnRlcmNlcHQgPSBjKDAsIDEpLCBsaW5ld2lkdGggPSAwLjQsDQogICAgY29sb3VyID0gIiNDQ0NDQ0MiLCBsaW5ldHlwZSA9ICJzb2xpZCINCiAgKSArDQogIGdlb21faGxpbmUoDQogICAgeWludGVyY2VwdCA9IGMoMC4yNSwgMC41LCAwLjc1KSwgbGluZXdpZHRoID0gMC40LA0KICAgIGNvbG91ciA9ICIjQ0NDQ0NDIiwgbGluZXR5cGUgPSAiZGFzaGVkIg0KICApICsNCiAgIyB5LWF4aXMgc2NhbGUNCiAgc2NhbGVfeV9jb250aW51b3VzKA0KICAgICMgbGltaXRzID0gYygtMzUsIDUpLA0KICAgIGJyZWFrcyA9IGMoMCwgMC4yNSwgMC41LCAwLjc1LCAxKSwNCiAgICBsYWJlbHMgPSBjKDAsIDAuMjUsIDAuNSwgMC43NSwgMSkNCiAgKSArDQogIHNjYWxlX3hfZGlzY3JldGUoDQogICAgbGFiZWxzID0gYygwLCAwLCAwLCAwKQ0KICApICsNCiAgIyBhZGQgZGF0YSBwb2ludHMNCiAgZ2VvbV9iZWVzd2FybSgNCiAgICBkYXRhID0gZGF0YV9wZXJfcHB0LA0KICAgIGFlcygNCiAgICAgIHkgPSBleHBfZml0X2xhbWJkYQ0KICAgICksDQogICAgYWxwaGEgPSAwLjEsDQogICAgc2l6ZSA9IDENCiAgKSArDQogIGdlb21fbGluZXJhbmdlKGFlcygNCiAgICB5bWluID0gbWVhbl9sZWFybmluZ19yYXRlIC0gY2lfbGVhcm5pbmdfcmF0ZSwNCiAgICB5bWF4ID0gbWVhbl9sZWFybmluZ19yYXRlICsgY2lfbGVhcm5pbmdfcmF0ZQ0KICApLCBhbHBoYSA9IDAuNSwgbHdkID0gMikgKw0KICBnZW9tX3BvaW50KCkNCg0KIyBzYXZlDQppZiAoc2F2ZV9wbG90cykgew0KICBnZ3NhdmUoDQogICAgcCwNCiAgICBmaWxlbmFtZSA9ICIuLi9kYXRhL2ZpZ3MvcGFwZXJfZmlncy9maWczX3dhc2hvdXRfbGVhcm5pbmdfcmF0ZXMucGRmIiwgZGV2aWNlID0gInBkZiIsDQogICAgaGVpZ2h0ID0gMiwgd2lkdGggPSBwZXJfZ3JvdXBfZmlnX3dpZHRoDQogICkNCn0NCg0KcA0KYGBgDQojIyMgQU5PVkEgLSAzIGxldmVscw0KYGBge3J9DQoodGVtcF9BTk9WQSA8LSBhb3ZfY2FyKA0KICBleHBfZml0X2xhbWJkYSB+IHBlcnQgKiBjdWUgKyBFcnJvcihwcGlkKSwNCiAgZGF0YV9wZXJfcHB0LA0KICBpbmNsdWRlX2FvdiA9IFRSVUUNCikpDQoNCnByaW50KCJCYXllcyBhbm92YXMgYW5kIGJheWVzIGZhY3RvcnM6IikNCnByaW50KCIiKQ0KDQpiZiA8LSBhbm92YUJGKGV4cF9maXRfbGFtYmRhIH4gcGVydCAqIGN1ZSwgZGF0YSA9IGRhdGEuZnJhbWUoZGF0YV9wZXJfcHB0KSwgcHJvZ3Jlc3MgPSBGQUxTRSkNCnByaW50KGJmKQ0KcHJpbnQoYmF5ZXNmYWN0b3JfaW5jbHVzaW9uKGJmKSkNCmBgYA0KYGBge3J9DQojIE5vdGU6IGRlZmF1bHQgbXVsdGlwbGljaXR5IGNvcnJlY3Rpb24gZm9yIHBhaXJzIHN1bW1hcnkgaXMgVHVrZXkgSFNEDQpwcmludCgiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRU1NcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpDQplbW1zX29iaiA8LSBlbW1lYW5zKHRlbXBfQU5PVkEsICJwZXJ0IikNCnByaW50KHB3cG0oZW1tc19vYmosIGRpZmZzID0gRkFMU0UpKQ0KDQojIEVmZmVjdCBzaXplIGlzIENvaGVuJ3MgRA0KZWZmX3NpemUoZW1tc19vYmosIGVkZiA9IHRlbXBfQU5PVkEkYW5vdmFfdGFibGUkYGRlbiBEZmBbMV0sIHNpZ21hID0gc2lnbWEodGVtcF9BTk9WQSRsbSkpDQoNCnByaW50KCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGdWxsIFR1a2V5IEhTRCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpDQpwcmludChUdWtleUhTRCh0ZW1wX0FOT1ZBJGFvdikpDQoNCnByaW50KGVmZl9zaXplKGVtbWVhbnModGVtcF9BTk9WQSRhb3YsIGMoInBlcnQiLCAiY3VlIikpLA0KICBlZGYgPSB0ZW1wX0FOT1ZBJGFub3ZhX3RhYmxlJGBkZW4gRGZgWzFdLA0KICBzaWdtYSA9IHNpZ21hKHRlbXBfQU5PVkEkbG0pDQopKQ0KYGBgDQojIyBXYXNob3V0IC0gRml0IEhpZ2ggUG9pbnRzIChTdGFydHMpDQpgYGB7ciwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTYsIG91dC53aWR0aD0iMTAwJSJ9DQpwIDwtIGRhdGFfcGVyX2dyb3VwICU+JQ0KICBnZ3Bsb3QoDQogICAgYWVzKHggPSBleHBlcmltZW50LCB5ID0gbWVhbl9oaWdoLCBjb2xvdXIgPSBleHBlcmltZW50KQ0KICApICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgbGFicygNCiAgICB4ID0gcGVyX2dyb3VwX3hfbGFicywNCiAgICB5ID0gIlN0YXJ0IFBvaW50IG9mIERlY2F5Ig0KICApICsNCiAgIyBmb3IgdGhlIGNvbG91ciBsZWdlbmQsIG9ubHkgc2hvdyB0aGUgZmlyc3QgNw0KICAjIE5vdGUgdGhpcyBkb2Vzbid0IHdvcmsgZm9yIHRoZSBwbG90bHkgcGxvdA0KICBndWlkZXMoDQogICAgY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkNCiAgKSArDQogICMgc2V0IGNvbG91ciBwYWxldHRlDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gcGFsbGV0ZV9saXN0KSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHBhbGxldGVfbGlzdCkgKw0KICAjIGFkZCBob3Jpem9udGFsIGxpbmVzDQogIGdlb21faGxpbmUoDQogICAgeWludGVyY2VwdCA9IGMoMCwgMSksIGxpbmV3aWR0aCA9IDAuNCwNCiAgICBjb2xvdXIgPSAiI0NDQ0NDQyIsIGxpbmV0eXBlID0gInNvbGlkIg0KICApICsNCiAgZ2VvbV9obGluZSgNCiAgICB5aW50ZXJjZXB0ID0gYygwLjUsIDEuNSksIGxpbmV3aWR0aCA9IDAuNCwNCiAgICBjb2xvdXIgPSAiI0NDQ0NDQyIsIGxpbmV0eXBlID0gImRhc2hlZCINCiAgKSArDQogICMgeS1heGlzIHNjYWxlDQogIHNjYWxlX3lfY29udGludW91cygNCiAgICBsaW1pdHMgPSBjKC0wLjUsIDEuNiksDQogICAgYnJlYWtzID0gYygtMC41LCAwLCAwLjUsIDEsIDEuNSksDQogICAgbGFiZWxzID0gYygtMC41LCAwLCAwLjUsIDEsIDEuNSkNCiAgKSArDQogIHNjYWxlX3hfZGlzY3JldGUoDQogICAgbGFiZWxzID0gYygwLCAwLCAwLCAwKQ0KICApICsNCiAgIyByZW1vdmUgYWxsIHggYXhpcyBsYWJlbHMNCiAgdGhlbWUoDQogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRfc2l6ZSkNCiAgKSArDQogICMgYWRkIGRhdGEgcG9pbnRzDQogIGdlb21fYmVlc3dhcm0oDQogICAgZGF0YSA9IGRhdGFfcGVyX3BwdCwNCiAgICBhZXMoDQogICAgICB5ID0gZXhwX2ZpdF9OMA0KICAgICksDQogICAgYWxwaGEgPSAwLjEsDQogICAgc2l6ZSA9IDENCiAgKSArDQogIGdlb21fbGluZXJhbmdlKGFlcygNCiAgICB5bWluID0gbWVhbl9oaWdoIC0gY2lfaGlnaCwNCiAgICB5bWF4ID0gbWVhbl9oaWdoICsgY2lfaGlnaA0KICApLCBhbHBoYSA9IDAuNSwgbHdkID0gMikgKw0KICBnZW9tX3BvaW50KCkNCg0KIyBzYXZlDQppZiAoc2F2ZV9wbG90cykgew0KICBnZ3NhdmUoDQogICAgcCwNCiAgICBmaWxlbmFtZSA9ICIuLi9kYXRhL2ZpZ3MvcGFwZXJfZmlncy9maWczX3dhc2hvdXRfc3RhcnRzLnBkZiIsIGRldmljZSA9ICJwZGYiLA0KICAgIGhlaWdodCA9IDIsIHdpZHRoID0gcGVyX2dyb3VwX2ZpZ193aWR0aA0KICApDQp9DQoNCnANCmBgYA0KIyMjIEFOT1ZBIC0gMyBsZXZlbHMNCmBgYHtyfQ0KKHRlbXBfQU5PVkEgPC0gYW92X2NhcigNCiAgZXhwX2ZpdF9OMCB+IHBlcnQgKiBjdWUgKyBFcnJvcihwcGlkKSwNCiAgZGF0YV9wZXJfcHB0LA0KICBpbmNsdWRlX2FvdiA9IFRSVUUNCikpDQoNCnByaW50KCJCYXllcyBhbm92YXMgYW5kIGJheWVzIGZhY3RvcnM6IikNCnByaW50KCIiKQ0KDQpiZiA8LSBhbm92YUJGKGV4cF9maXRfTjAgfiBwZXJ0ICogY3VlLCBkYXRhID0gZGF0YS5mcmFtZShkYXRhX3Blcl9wcHQpLCBwcm9ncmVzcyA9IEZBTFNFKQ0KcHJpbnQoYmYpDQpwcmludChiYXllc2ZhY3Rvcl9pbmNsdXNpb24oYmYpKQ0KYGBgDQpgYGB7cn0NCiMgTm90ZTogZGVmYXVsdCBtdWx0aXBsaWNpdHkgY29ycmVjdGlvbiBmb3IgcGFpcnMgc3VtbWFyeSBpcyBUdWtleSBIU0QNCnByaW50KCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBFTU1zIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIikNCmVtbXNfb2JqIDwtIGVtbWVhbnModGVtcF9BTk9WQSwgInBlcnQiKQ0KcHJpbnQocHdwbShlbW1zX29iaiwgZGlmZnMgPSBGQUxTRSkpDQoNCiMgRWZmZWN0IHNpemUgaXMgQ29oZW4ncyBEDQplZmZfc2l6ZShlbW1zX29iaiwgZWRmID0gdGVtcF9BTk9WQSRhbm92YV90YWJsZSRgZGVuIERmYFsxXSwgc2lnbWEgPSBzaWdtYSh0ZW1wX0FOT1ZBJGxtKSkNCg0KcHJpbnQoIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZ1bGwgVHVrZXkgSFNEIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIikNCnByaW50KFR1a2V5SFNEKHRlbXBfQU5PVkEkYW92KSkNCg0KcHJpbnQoZWZmX3NpemUoZW1tZWFucyh0ZW1wX0FOT1ZBJGFvdiwgYygicGVydCIsICJjdWUiKSksDQogIGVkZiA9IHRlbXBfQU5PVkEkYW5vdmFfdGFibGUkYGRlbiBEZmBbMV0sDQogIHNpZ21hID0gc2lnbWEodGVtcF9BTk9WQSRsbSkNCikpDQpgYGANCg0KIyBBbHRlcm5hdGUgV2FzaG91dCBQaGFzZXMgDQpUaGVzZSBpbmNsdWRlIHRoZSBsYXN0IHRyaWFsIG9mIHRoZSBUcmFpbmluZyBwaGFzZSBmb3IgYWxsIEN1ZWQgY29uZGl0aW9ucy4NCg0KIyMgTm9ybWFsaXplZCBXYXNob3V0IFBoYXNlcw0KYGBge3IsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD02LCBvdXQud2lkdGg9IjEwMCUifQ0KIyByZXN0IG9mIHRoZSBleHBzDQpkYXRhX3Blcl9ncm91cCA8LSBvbW5pYnVzX2RmICU+JQ0KICBmaWx0ZXIoDQogICAgZXhwZXJpbWVudCAlaW4lIGMoDQogICAgICAicm90MzBfY3VlZF90aWx0IiwgInJvdDMwX3VuY3VlZCIsDQogICAgICAiY3VydmVkX2N1ZWRfdGlsdCIsICJjdXJ2ZWRfdW5jdWVkIg0KICAgICksDQogICAgdHJpYWxfbnVtID49IDIxNCwNCiAgICBhbHRfd2FzaG91dF9ibG9jayA9PSBUUlVFLA0KICApICU+JQ0KICBhcnJhbmdlKGV4cGVyaW1lbnQsIHBwaWQsIHRyaWFsX251bSkgJT4lDQogIGdyb3VwX2J5KGV4cGVyaW1lbnQsIHRyaWFsX251bSkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBtZWFuX2RldmlhdGlvbiA9IG1lYW4obm9ybV90aHJvd19kZXZpYXRpb24pLA0KICAgIGNpX2RldmlhdGlvbiA9IHZlY3Rvcl9jb25maW50KG5vcm1fdGhyb3dfZGV2aWF0aW9uKSwNCiAgICAuZ3JvdXBzID0gImRyb3AiDQogICkNCg0KIyBOT1RFOiB0aGlzIGNhbid0IGJlIGNvbWJpbmVkIHdpdGggYWJvdmUgc2luY2Ugd2UgYXJlIHVzaW5nIG5yb3cNCmRhdGFfcGVyX2dyb3VwIDwtIGRhdGFfcGVyX2dyb3VwICU+JQ0KICBtdXRhdGUoZHVtbXlfeCA9IHJlcCgxOjQwLA0KICAgIGxlbmd0aC5vdXQgPSBucm93KGRhdGFfcGVyX2dyb3VwKQ0KICApKQ0KDQojIGFkZCBhIGR1bW15IGNvbHVtbiB3aXRoIHJlcGVhdGluZyBzZXF1ZW5jZQ0KDQoNCiMgc2V0IHVwIHBsb3QNCnAgPC0gZGF0YV9wZXJfZ3JvdXAgJT4lDQogIGdncGxvdCgNCiAgICBhZXMoDQogICAgICB4ID0gZHVtbXlfeCwgeSA9IG1lYW5fZGV2aWF0aW9uLCBjb2xvdXIgPSBleHBlcmltZW50DQogICAgKQ0KICApICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgdGhlbWUoDQogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRfc2l6ZSkNCiAgKSArDQogIGxhYnMoDQogICAgeCA9ICJUcmlhbCIsDQogICAgeSA9ICJOb3JtYWxpemVkIFRocm93IEFuZ2xlIg0KICApICsNCiAgIyBhZGQgaG9yaXpvbnRhbCBsaW5lcw0KICBnZW9tX2hsaW5lKA0KICAgIHlpbnRlcmNlcHQgPSBjKDAsIDEpLCBsaW5ld2lkdGggPSAwLjQsDQogICAgY29sb3VyID0gIiNDQ0NDQ0MiLCBsaW5ldHlwZSA9ICJzb2xpZCINCiAgKSArDQogIGdlb21faGxpbmUoDQogICAgeWludGVyY2VwdCA9IGMoMC41LCAxLjUpLCBsaW5ld2lkdGggPSAwLjQsDQogICAgY29sb3VyID0gIiNDQ0NDQ0MiLCBsaW5ldHlwZSA9ICJkYXNoZWQiDQogICkgKw0KICAjIHNldCBjb2xvdXIgcGFsZXR0ZQ0KICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHBhbGxldGVfbGlzdCkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBwYWxsZXRlX2xpc3QpICsgIyBzY2FsZSBheGVzDQogIHNjYWxlX3lfY29udGludW91cygNCiAgICBicmVha3MgPSBjKDAsIDAuNSwgMSwgMS41KSwNCiAgICBsYWJlbHMgPSBjKDAsIDAuNSwgMSwgMS41KQ0KICApICsNCiAgc2NhbGVfeF9jb250aW51b3VzKA0KICAgIGJyZWFrcyA9IGN1cnZlX3hfYnJlYWtzLA0KICAgIGxhYmVscyA9IGN1cnZlX3hfYnJlYWtzDQogICkNCg0KIyBhZGQgY29uZmlkZW5jZSBpbnRlcnZhbHMgYW5kIGRhdGEgcG9pbnRzDQpmb3IgKHVuaXFfZXhwIGluIHVuaXF1ZShkYXRhX3Blcl9ncm91cCRleHBlcmltZW50KSkgew0KICAjIGdldCB0aGUgZGF0YSBmb3IgdGhpcyBibG9jaw0KICB0b19wbG90X2RhdGEgPC0gZmlsdGVyKGRhdGFfcGVyX2dyb3VwLCBleHBlcmltZW50ID09IHVuaXFfZXhwKQ0KDQogIHAgPC0gcCArIGdlb21fcmliYm9uKA0KICAgIGRhdGEgPSB0b19wbG90X2RhdGEsDQogICAgYWVzKA0KICAgICAgeW1pbiA9IG1lYW5fZGV2aWF0aW9uIC0gY2lfZGV2aWF0aW9uLA0KICAgICAgeW1heCA9IG1lYW5fZGV2aWF0aW9uICsgY2lfZGV2aWF0aW9uLA0KICAgICAgZmlsbCA9IGV4cGVyaW1lbnQNCiAgICApLCBjb2xvdXIgPSBOQSwgYWxwaGEgPSAwLjMNCiAgKSArIGdlb21fbGluZSgNCiAgICBkYXRhID0gdG9fcGxvdF9kYXRhDQogICkNCn0NCg0KIyBzYXZlDQppZiAoc2F2ZV9wbG90cykgew0KICBnZ3NhdmUoDQogICAgcCwNCiAgICBmaWxlbmFtZSA9ICIuLi9kYXRhL2ZpZ3MvcGFwZXJfZmlncy9maWczX2N1cnZlZF9hbHRfd2FzaG91dC5wZGYiLCBkZXZpY2UgPSAicGRmIiwNCiAgICBoZWlnaHQgPSAyLCB3aWR0aCA9IDIuNQ0KICApDQp9DQoNCnANCiMgZ2dwbG90bHkocCkNCmBgYA0KYGBge3J9DQpmaXR0ZWRfZGF0YSA8LSBmaXR0ZWRfYWx0X3dhc2hvdXRfZGYgJT4lDQogIGZpbHRlcigNCiAgICBleHBlcmltZW50ICVpbiUgYygNCiAgICAgICJyb3QzMF9jdWVkX3RpbHQiLCAicm90MzBfdW5jdWVkIiwNCiAgICAgICJjdXJ2ZWRfY3VlZF90aWx0IiwgImN1cnZlZF91bmN1ZWQiDQogICAgKSwNCiAgICBwaGFzZSA9PSAid2FzaG91dCINCiAgKSAlPiUNCiAgbXV0YXRlKA0KICAgIHBlcnQgPSBmYWN0b3Ioc3RyX3NwbGl0X2ZpeGVkKGV4cGVyaW1lbnQsICJfIiwgMilbLCAxXSksDQogICAgY3VlID0gZmFjdG9yKHN0cl9zcGxpdF9maXhlZChleHBlcmltZW50LCAiXyIsIDIpWywgMl0pDQogICkNCg0KcCA8LSBmaXR0ZWRfZGF0YSAlPiUNCiAgZ2dwbG90KA0KICAgIGFlcyh4ID0geCArIDEsIHkgPSB5LCBjb2xvdXIgPSBleHBlcmltZW50KQ0KICApICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgdGhlbWUoDQogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRfc2l6ZSkNCiAgKSArDQogIGxhYnMoDQogICAgeCA9ICJUcmlhbCIsDQogICAgeSA9ICJOb3JtYWxpemVkIFRocm93IEFuZ2xlIg0KICApICsNCiAgIyBhZGQgaG9yaXpvbnRhbCBsaW5lcw0KICBnZW9tX2hsaW5lKA0KICAgIHlpbnRlcmNlcHQgPSBjKDAsIDEpLCBsaW5ld2lkdGggPSAwLjQsDQogICAgY29sb3VyID0gIiNDQ0NDQ0MiLCBsaW5ldHlwZSA9ICJzb2xpZCINCiAgKSArDQogIGdlb21faGxpbmUoDQogICAgeWludGVyY2VwdCA9IGMoMC41LCAxLjUpLCBsaW5ld2lkdGggPSAwLjQsDQogICAgY29sb3VyID0gIiNDQ0NDQ0MiLCBsaW5ldHlwZSA9ICJkYXNoZWQiDQogICkgKw0KICAjIHNldCBjb2xvdXIgcGFsZXR0ZQ0KICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHBhbGxldGVfbGlzdCkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBwYWxsZXRlX2xpc3QpICsgIyBzY2FsZSBheGVzDQogIHNjYWxlX3lfY29udGludW91cygNCiAgICBicmVha3MgPSBjKDAsIDAuNSwgMSwgMS41KSwNCiAgICBsYWJlbHMgPSBjKDAsIDAuNSwgMSwgMS41KSwNCiAgICBsaW1pdHMgPSBjKC0wLjI1LCAxLjUpDQogICkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoDQogICAgYnJlYWtzID0gY3VydmVfeF9icmVha3MsDQogICAgbGFiZWxzID0gY3VydmVfeF9icmVha3MNCiAgKSArDQogIGdlb21fbGluZSgpDQoNCiMgc2F2ZQ0KaWYgKHNhdmVfcGxvdHMpIHsNCiAgZ2dzYXZlKA0KICAgIHAsDQogICAgZmlsZW5hbWUgPSAiLi4vZGF0YS9maWdzL3BhcGVyX2ZpZ3MvZmlnM19jdXJ2ZWRfYWx0X3dhc2hvdXRfZml0dGVkX29ubHkucGRmIiwgZGV2aWNlID0gInBkZiIsDQogICAgaGVpZ2h0ID0gMiwgd2lkdGggPSBjdXJ2ZV9maWdfd2lkdGgNCiAgKQ0KfQ0KDQpwDQpgYGANCiMjIFdhc2hvdXQgLSBGaXQgTGVhcm5pbmcgUmF0ZXMNCmBgYHtyLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9Niwgb3V0LndpZHRoPSIxMDAlIn0NCmRhdGFfcGVyX3BwdCA8LSBhbHRfd2FzaG91dF9yYXRlcyAlPiUNCiAgZmlsdGVyKA0KICAgIGV4cGVyaW1lbnQgJWluJSBjKA0KICAgICAgIyAiYWNjZWxfY3VlZF90aWx0IiwgImFjY2VsX3VuY3VlZCIsDQogICAgICAicm90MzBfY3VlZF90aWx0IiwgInJvdDMwX3VuY3VlZCIsDQogICAgICAiY3VydmVkX2N1ZWRfdGlsdCIsICJjdXJ2ZWRfdW5jdWVkIg0KICAgICkNCiAgKSAlPiUNCiAgbXV0YXRlKA0KICAgIHBlcnQgPSBmYWN0b3Ioc3RyX3NwbGl0X2ZpeGVkKGV4cGVyaW1lbnQsICJfIiwgMilbLCAxXSksDQogICAgY3VlID0gZmFjdG9yKHN0cl9zcGxpdF9maXhlZChleHBlcmltZW50LCAiXyIsIDIpWywgMl0pLA0KICAgIHBwaWQgPSBmYWN0b3IocHBpZCkNCiAgKQ0KDQpkYXRhX3Blcl9ncm91cCA8LSBkYXRhX3Blcl9wcHQgJT4lDQogIGdyb3VwX2J5KGV4cGVyaW1lbnQpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgbWVhbl9sZWFybmluZ19yYXRlID0gbWVhbihleHBfZml0X2xhbWJkYSksDQogICAgY2lfbGVhcm5pbmdfcmF0ZSA9IHZlY3Rvcl9jb25maW50KGV4cF9maXRfbGFtYmRhKSwNCiAgICBtZWFuX2hpZ2ggPSBtZWFuKGV4cF9maXRfTjApLA0KICAgIGNpX2hpZ2ggPSB2ZWN0b3JfY29uZmludChleHBfZml0X04wKSwNCiAgICAuZ3JvdXBzID0gImRyb3AiDQogICkNCg0KcCA8LSBkYXRhX3Blcl9ncm91cCAlPiUNCiAgZ2dwbG90KA0KICAgIGFlcyh4ID0gZXhwZXJpbWVudCwgeSA9IG1lYW5fbGVhcm5pbmdfcmF0ZSwgY29sb3VyID0gZXhwZXJpbWVudCkNCiAgKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIGxhYnMoDQogICAgeCA9IHBlcl9ncm91cF94X2xhYnMsDQogICAgeSA9ICJEZWNheSBSYXRlIg0KICApICsNCiAgIyByZW1vdmUgYWxsIHggYXhpcyBsYWJlbHMNCiAgdGhlbWUoDQogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRfc2l6ZSkNCiAgKSArDQogICMgY29sb3VyIGxlZ2VuZCBzZXR0aW5ncw0KICBndWlkZXMoDQogICAgY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkNCiAgKSArDQogICMgc2V0IGNvbG91ciBwYWxldHRlDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gcGFsbGV0ZV9saXN0KSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKA0KICAgIHZhbHVlcyA9IHBhbGxldGVfbGlzdA0KICApICsNCiAgIyBhZGQgaG9yaXpvbnRhbCBsaW5lcw0KICBnZW9tX2hsaW5lKA0KICAgIHlpbnRlcmNlcHQgPSBjKDAsIDEpLCBsaW5ld2lkdGggPSAwLjQsDQogICAgY29sb3VyID0gIiNDQ0NDQ0MiLCBsaW5ldHlwZSA9ICJzb2xpZCINCiAgKSArDQogIGdlb21faGxpbmUoDQogICAgeWludGVyY2VwdCA9IGMoMC4yNSwgMC41LCAwLjc1KSwgbGluZXdpZHRoID0gMC40LA0KICAgIGNvbG91ciA9ICIjQ0NDQ0NDIiwgbGluZXR5cGUgPSAiZGFzaGVkIg0KICApICsNCiAgIyB5LWF4aXMgc2NhbGUNCiAgc2NhbGVfeV9jb250aW51b3VzKA0KICAgICMgbGltaXRzID0gYygtMzUsIDUpLA0KICAgIGJyZWFrcyA9IGMoMCwgMC4yNSwgMC41LCAwLjc1LCAxKSwNCiAgICBsYWJlbHMgPSBjKDAsIDAuMjUsIDAuNSwgMC43NSwgMSkNCiAgKSArDQogIHNjYWxlX3hfZGlzY3JldGUoDQogICAgbGFiZWxzID0gYygwLCAwLCAwLCAwKQ0KICApICsNCiAgIyBhZGQgZGF0YSBwb2ludHMNCiAgZ2VvbV9iZWVzd2FybSgNCiAgICBkYXRhID0gZGF0YV9wZXJfcHB0LA0KICAgIGFlcygNCiAgICAgIHkgPSBleHBfZml0X2xhbWJkYQ0KICAgICksDQogICAgYWxwaGEgPSAwLjEsDQogICAgc2l6ZSA9IDENCiAgKSArDQogIGdlb21fbGluZXJhbmdlKGFlcygNCiAgICB5bWluID0gbWVhbl9sZWFybmluZ19yYXRlIC0gY2lfbGVhcm5pbmdfcmF0ZSwNCiAgICB5bWF4ID0gbWVhbl9sZWFybmluZ19yYXRlICsgY2lfbGVhcm5pbmdfcmF0ZQ0KICApLCBhbHBoYSA9IDAuNSwgbHdkID0gMikgKw0KICBnZW9tX3BvaW50KCkNCg0KIyBzYXZlDQppZiAoc2F2ZV9wbG90cykgew0KICBnZ3NhdmUoDQogICAgcCwNCiAgICBmaWxlbmFtZSA9ICIuLi9kYXRhL2ZpZ3MvcGFwZXJfZmlncy9maWczX2N1cnZlZF9hbHRfd2FzaG91dF9sZWFybmluZ19yYXRlcy5wZGYiLCBkZXZpY2UgPSAicGRmIiwNCiAgICBoZWlnaHQgPSAyLCB3aWR0aCA9IHBlcl9ncm91cF9maWdfd2lkdGgNCiAgKQ0KfQ0KDQpwDQpgYGANCg0KYGBge3J9DQoodGVtcF9BTk9WQSA8LSBhb3ZfY2FyKA0KICBleHBfZml0X2xhbWJkYSB+IHBlcnQgKiBjdWUgKyBFcnJvcihwcGlkKSwNCiAgZGF0YV9wZXJfcHB0LA0KICBpbmNsdWRlX2FvdiA9IFRSVUUNCikpDQoNCnByaW50KCJCYXllcyBhbm92YXMgYW5kIGJheWVzIGZhY3RvcnM6IikNCnByaW50KCIiKQ0KDQpiZiA8LSBhbm92YUJGKGV4cF9maXRfbGFtYmRhIH4gcGVydCAqIGN1ZSwgZGF0YSA9IGRhdGEuZnJhbWUoZGF0YV9wZXJfcHB0KSwgcHJvZ3Jlc3MgPSBGQUxTRSkNCnByaW50KGJmKQ0KcHJpbnQoYmF5ZXNmYWN0b3JfaW5jbHVzaW9uKGJmKSkNCmBgYA0KUGFpcndpc2UgY29tcGFyaXNvbnM6DQpgYGB7cn0NCiMgcG9zdGhvYyB0ZXN0cw0KIyAobTEgPC0gZW1tZWFucyh0ZW1wX0FOT1ZBLCB+cGVydCkpDQojIHByaW50KCJQYWlyd2lzZSBjb21wYXJpc29uczoiKQ0KIyBwcmludChzdW1tYXJ5KHBhaXJzKG0xKSwgYWRqdXN0ID0gInR1a2V5IikpICMgTm90ZTogZGVmYXVsdCBtdWx0aXBsaWNpdHkgY29ycmVjdGlvbiBmb3IgcGFpcnMgc3VtbWFyeSBpcyBUdWtleSBIU0QNCg0KIyBOb3RlOiBkZWZhdWx0IG11bHRpcGxpY2l0eSBjb3JyZWN0aW9uIGZvciBwYWlycyBzdW1tYXJ5IGlzIFR1a2V5IEhTRA0KcHJpbnQoIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEVNTXMgY3VlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIikNCmVtbXNfb2JqIDwtIGVtbWVhbnModGVtcF9BTk9WQSwgImN1ZSIpDQpwcmludChwd3BtKGVtbXNfb2JqLCBkaWZmcyA9IEZBTFNFKSkNCg0KIyBFZmZlY3Qgc2l6ZSBpcyBDb2hlbidzIEQNCmVmZl9zaXplKGVtbXNfb2JqLCBlZGYgPSB0ZW1wX0FOT1ZBJGFub3ZhX3RhYmxlJGBkZW4gRGZgWzFdLCBzaWdtYSA9IHNpZ21hKHRlbXBfQU5PVkEkbG0pKQ0KDQpwcmludCgiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRU1NcyBwZXJ0cyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpDQplbW1zX29iaiA8LSBlbW1lYW5zKHRlbXBfQU5PVkEsICJwZXJ0IikNCnByaW50KHB3cG0oZW1tc19vYmosIGRpZmZzID0gRkFMU0UpKQ0KDQojIEVmZmVjdCBzaXplIGlzIENvaGVuJ3MgRA0KZWZmX3NpemUoZW1tc19vYmosIGVkZiA9IHRlbXBfQU5PVkEkYW5vdmFfdGFibGUkYGRlbiBEZmBbMV0sIHNpZ21hID0gc2lnbWEodGVtcF9BTk9WQSRsbSkpDQoNCnByaW50KCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGdWxsIFR1a2V5IEhTRCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpDQpwcmludChUdWtleUhTRCh0ZW1wX0FOT1ZBJGFvdikpDQoNCnByaW50KGVmZl9zaXplKGVtbWVhbnModGVtcF9BTk9WQSRhb3YsIGMoInBlcnQiLCAiY3VlIikpLA0KICBlZGYgPSB0ZW1wX0FOT1ZBJGFub3ZhX3RhYmxlJGBkZW4gRGZgWzFdLA0KICBzaWdtYSA9IHNpZ21hKHRlbXBfQU5PVkEkbG0pDQopKQ0KYGBgDQoNCiMjIFdhc2hvdXQgLSBGaXQgSGlnaCBQb2ludHMgKFN0YXJ0cykNCmBgYHtyLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9Niwgb3V0LndpZHRoPSIxMDAlIn0NCnAgPC0gZGF0YV9wZXJfZ3JvdXAgJT4lDQogIGdncGxvdCgNCiAgICBhZXMoeCA9IGV4cGVyaW1lbnQsIHkgPSBtZWFuX2hpZ2gsIGNvbG91ciA9IGV4cGVyaW1lbnQpDQogICkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICBsYWJzKA0KICAgIHggPSBwZXJfZ3JvdXBfeF9sYWJzLA0KICAgIHkgPSAiU3RhcnQgUG9pbnQgb2YgRGVjYXkiDQogICkgKw0KICAjIGZvciB0aGUgY29sb3VyIGxlZ2VuZCwgb25seSBzaG93IHRoZSBmaXJzdCA3DQogICMgTm90ZSB0aGlzIGRvZXNuJ3Qgd29yayBmb3IgdGhlIHBsb3RseSBwbG90DQogIGd1aWRlcygNCiAgICBjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChhbHBoYSA9IDEpKQ0KICApICsNCiAgIyBzZXQgY29sb3VyIHBhbGV0dGUNCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBwYWxsZXRlX2xpc3QpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gcGFsbGV0ZV9saXN0KSArDQogICMgYWRkIGhvcml6b250YWwgbGluZXMNCiAgZ2VvbV9obGluZSgNCiAgICB5aW50ZXJjZXB0ID0gYygwLCAxKSwgbGluZXdpZHRoID0gMC40LA0KICAgIGNvbG91ciA9ICIjQ0NDQ0NDIiwgbGluZXR5cGUgPSAic29saWQiDQogICkgKw0KICBnZW9tX2hsaW5lKA0KICAgIHlpbnRlcmNlcHQgPSBjKDAuNSwgMS41KSwgbGluZXdpZHRoID0gMC40LA0KICAgIGNvbG91ciA9ICIjQ0NDQ0NDIiwgbGluZXR5cGUgPSAiZGFzaGVkIg0KICApICsNCiAgIyB5LWF4aXMgc2NhbGUNCiAgc2NhbGVfeV9jb250aW51b3VzKA0KICAgIGxpbWl0cyA9IGMoLTAuNSwgMS42KSwNCiAgICBicmVha3MgPSBjKC0wLjUsIDAsIDAuNSwgMSwgMS41KSwNCiAgICBsYWJlbHMgPSBjKC0wLjUsIDAsIDAuNSwgMSwgMS41KQ0KICApICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgNCiAgICBsYWJlbHMgPSBjKDAsIDAsIDAsIDApDQogICkgKw0KICAjIHJlbW92ZSBhbGwgeCBheGlzIGxhYmVscw0KICB0aGVtZSgNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dF9zaXplKQ0KICApICsNCiAgIyBhZGQgZGF0YSBwb2ludHMNCiAgZ2VvbV9iZWVzd2FybSgNCiAgICBkYXRhID0gZGF0YV9wZXJfcHB0LA0KICAgIGFlcygNCiAgICAgIHkgPSBleHBfZml0X04wDQogICAgKSwNCiAgICBhbHBoYSA9IDAuMSwNCiAgICBzaXplID0gMQ0KICApICsNCiAgZ2VvbV9saW5lcmFuZ2UoYWVzKA0KICAgIHltaW4gPSBtZWFuX2hpZ2ggLSBjaV9oaWdoLA0KICAgIHltYXggPSBtZWFuX2hpZ2ggKyBjaV9oaWdoDQogICksIGFscGhhID0gMC41LCBsd2QgPSAyKSArDQogIGdlb21fcG9pbnQoKQ0KDQojIHNhdmUNCmlmIChzYXZlX3Bsb3RzKSB7DQogIGdnc2F2ZSgNCiAgICBwLA0KICAgIGZpbGVuYW1lID0gIi4uL2RhdGEvZmlncy9wYXBlcl9maWdzL2ZpZzNfY3VydmVkX2FsdF93YXNob3V0X3N0YXJ0cy5wZGYiLCBkZXZpY2UgPSAicGRmIiwNCiAgICBoZWlnaHQgPSAyLCB3aWR0aCA9IHBlcl9ncm91cF9maWdfd2lkdGgNCiAgKQ0KfQ0KDQpwDQpgYGANCg0KYGBge3J9DQoodGVtcF9BTk9WQSA8LSBhb3ZfY2FyKA0KICBleHBfZml0X04wIH4gcGVydCAqIGN1ZSArIEVycm9yKHBwaWQpLA0KICBkYXRhX3Blcl9wcHQsDQogIGluY2x1ZGVfYW92ID0gVFJVRQ0KKSkNCg0KcHJpbnQoIkJheWVzIGFub3ZhcyBhbmQgYmF5ZXMgZmFjdG9yczoiKQ0KcHJpbnQoIiIpDQoNCmJmIDwtIGFub3ZhQkYoZXhwX2ZpdF9OMCB+IHBlcnQgKiBjdWUsIGRhdGEgPSBkYXRhLmZyYW1lKGRhdGFfcGVyX3BwdCksIHByb2dyZXNzID0gRkFMU0UpDQpwcmludChiZikNCnByaW50KGJheWVzZmFjdG9yX2luY2x1c2lvbihiZikpDQpgYGANClBhaXJ3aXNlIGNvbXBhcmlzb25zOg0KYGBge3J9DQojIHBvc3Rob2MgdGVzdHMNCiMgKG0xIDwtIGVtbWVhbnModGVtcF9BTk9WQSwgfnBlcnQpKQ0KIyBwcmludCgiUGFpcndpc2UgY29tcGFyaXNvbnM6IikNCiMgcHJpbnQoc3VtbWFyeShwYWlycyhtMSksIGFkanVzdCA9ICJ0dWtleSIpKSAjIE5vdGU6IGRlZmF1bHQgbXVsdGlwbGljaXR5IGNvcnJlY3Rpb24gZm9yIHBhaXJzIHN1bW1hcnkgaXMgVHVrZXkgSFNEDQoNCiMgTm90ZTogZGVmYXVsdCBtdWx0aXBsaWNpdHkgY29ycmVjdGlvbiBmb3IgcGFpcnMgc3VtbWFyeSBpcyBUdWtleSBIU0QNCnByaW50KCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBFTU1zIGN1ZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpDQplbW1zX29iaiA8LSBlbW1lYW5zKHRlbXBfQU5PVkEsICJjdWUiKQ0KcHJpbnQocHdwbShlbW1zX29iaiwgZGlmZnMgPSBGQUxTRSkpDQoNCiMgRWZmZWN0IHNpemUgaXMgQ29oZW4ncyBEDQplZmZfc2l6ZShlbW1zX29iaiwgZWRmID0gdGVtcF9BTk9WQSRhbm92YV90YWJsZSRgZGVuIERmYFsxXSwgc2lnbWEgPSBzaWdtYSh0ZW1wX0FOT1ZBJGxtKSkNCg0KcHJpbnQoIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEVNTXMgcGVydHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iKQ0KZW1tc19vYmogPC0gZW1tZWFucyh0ZW1wX0FOT1ZBLCAicGVydCIpDQpwcmludChwd3BtKGVtbXNfb2JqLCBkaWZmcyA9IEZBTFNFKSkNCg0KIyBFZmZlY3Qgc2l6ZSBpcyBDb2hlbidzIEQNCmVmZl9zaXplKGVtbXNfb2JqLCBlZGYgPSB0ZW1wX0FOT1ZBJGFub3ZhX3RhYmxlJGBkZW4gRGZgWzFdLCBzaWdtYSA9IHNpZ21hKHRlbXBfQU5PVkEkbG0pKQ0KDQpwcmludCgiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRnVsbCBUdWtleSBIU0QgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iKQ0KcHJpbnQoVHVrZXlIU0QodGVtcF9BTk9WQSRhb3YpKQ0KDQpwcmludChlZmZfc2l6ZShlbW1lYW5zKHRlbXBfQU5PVkEkYW92LCBjKCJwZXJ0IiwgImN1ZSIpKSwNCiAgZWRmID0gdGVtcF9BTk9WQSRhbm92YV90YWJsZSRgZGVuIERmYFsxXSwNCiAgc2lnbWEgPSBzaWdtYSh0ZW1wX0FOT1ZBJGxtKQ0KKSkNCmBgYA0KYGBge3J9DQoNCmBgYA0KDQo=